Compare commits

...

8 Commits

  1. 2
      .github/workflows/backport.yaml
  2. 3
      .github/workflows/copr-build.yaml
  3. 45
      .github/workflows/rawhide-backport.yaml
  4. 38
      .github/workflows/rawhide-copr-build.yaml
  5. 13
      build.sh
  6. 3
      centos-10/SOURCES/libvirt-11.8.0.tar.xz
  7. 3
      centos-10/SOURCES/libvirt-11.9.0.tar.xz
  8. 3
      centos-10/SOURCES/zfs-2.2.10.tar.gz
  9. 3
      centos-10/SOURCES/zfs-2.2.8.tar.gz
  10. 3
      centos-10/SOURCES/zfs-2.2.9.tar.gz
  11. 4
      centos-10/SPECS/zfs-dkms.spec
  12. 5
      centos-10/SPECS/zfs.spec
  13. 3
      centos-9/SOURCES/libvirt-11.8.0.tar.xz
  14. 3
      centos-9/SOURCES/libvirt-11.9.0.tar.xz
  15. 73
      centos-9/SOURCES/libvirt-Fix-documentation-of-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES.patch
  16. 54
      centos-9/SOURCES/libvirt-Introduce-EXPAND_CPU_FEATURES-flag-for-domain-capabilities.patch
  17. 59
      centos-9/SOURCES/libvirt-Introduce-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES-flag.patch
  18. 160
      centos-9/SOURCES/libvirt-conf-Add-iommufd-fdgroup-support.patch
  19. 218
      centos-9/SOURCES/libvirt-conf-Introduce-domain-iommufd-element.patch
  20. 330
      centos-9/SOURCES/libvirt-conf-Move-and-rename-virStorageSourceFDTuple-object.patch
  21. 113
      centos-9/SOURCES/libvirt-conf-Parse-hyperv-features-even-for-host-model.patch
  22. 80
      centos-9/SOURCES/libvirt-conf-Refactor-virHostdevIsPCIDevice.patch
  23. 158
      centos-9/SOURCES/libvirt-cpu-Introduce-virCPUUpdateFeatures.patch
  24. 109
      centos-9/SOURCES/libvirt-cpu_conf-Introduce-virCPUDefSortFeatures.patch
  25. 109
      centos-9/SOURCES/libvirt-cpu_x86-Introduce-virCPUx86DataAddMSR.patch
  26. 34
      centos-9/SOURCES/libvirt-docs-Clarify-host-model-description-in-domain-capabilities.patch
  27. 24245
      centos-9/SOURCES/libvirt-domaincapstest-Test-EXPAND_CPU_FEATURES-flag.patch
  28. 22680
      centos-9/SOURCES/libvirt-domaincapstest-Test-SUPPORTED_CPU_FEATURES-flag.patch
  29. 45
      centos-9/SOURCES/libvirt-hypervisor-Call-virWaitForDevices-after-detaching-host-devices.patch
  30. 98
      centos-9/SOURCES/libvirt-hypervisor-Fix-virHostdevNeedsVFIO-detection.patch
  31. 51
      centos-9/SOURCES/libvirt-qemu-Expand-call-to-qemuDomainNeedsVFIO.patch
  32. 245
      centos-9/SOURCES/libvirt-qemu-Fix-IOMMUFD-and-VFIO-security-labels.patch
  33. 60
      centos-9/SOURCES/libvirt-qemu-Fix-job-handling-when-domain-dies-in-post-copy-migration.patch
  34. 47
      centos-9/SOURCES/libvirt-qemu-Implement-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES.patch
  35. 127
      centos-9/SOURCES/libvirt-qemu-Implement-iommufd-fdgroup.patch
  36. 119
      centos-9/SOURCES/libvirt-qemu-Implement-iommufd.patch
  37. 196
      centos-9/SOURCES/libvirt-qemu-Move-domain-caps-flags-handling-to-virQEMUCapsFillDomainCPUHostModel.patch
  38. 107
      centos-9/SOURCES/libvirt-qemu-Update-qemuDomainNeedsVFIO-to-ignore-PCI-hostdev-with-IOMMUFD.patch
  39. 59
      centos-9/SOURCES/libvirt-qemu-Wire-up-new-hyperv-host-model-mode-behavior.patch
  40. 46
      centos-9/SOURCES/libvirt-qemuMigrationSrcBeginPhase-Don-t-call-qemuBlockNodesEnsureActive-with-offline-VM.patch
  41. 45
      centos-9/SOURCES/libvirt-qemuMigrationSrcBeginXML-Don-t-call-qemuMigrationSrcBeginPhaseBlockDirtyBitmaps-with-offline-VM.patch
  42. 3806
      centos-9/SOURCES/libvirt-qemu_capabilities-Always-sort-features-in-host-model-CPU.patch
  43. 158
      centos-9/SOURCES/libvirt-qemu_capabilities-Cache-expanded-CPU.patch
  44. 156
      centos-9/SOURCES/libvirt-qemu_capabilities-Fix-domain-capabilities-on-AMD-CPUs.patch
  45. 71
      centos-9/SOURCES/libvirt-qemu_capabilities-Split-conditions-in-virQEMUCapsInitHostCPUModel.patch
  46. 150
      centos-9/SOURCES/libvirt-qemu_capabilities-Split-virQEMUCapsFillDomainCPUCaps.patch
  47. 65
      centos-9/SOURCES/libvirt-qemu_capabilities-Use-g_autoptr-in-virQEMUCapsInitHostCPUModel.patch
  48. 611
      centos-9/SOURCES/libvirt-security-Cleanup-hostdev-label-error-logic.patch
  49. 118
      centos-9/SOURCES/libvirt-security_apparmor-Use-g_auto-in-AppArmorSetSecurityHostdevLabel.patch
  50. 152
      centos-9/SOURCES/libvirt-src-Use-virHostdevIsPCIDeviceWith-to-check-for-IOMMUFD.patch
  51. 266
      centos-9/SOURCES/libvirt-tests-Add-iommufd-fdgroup-test.patch
  52. 127
      centos-9/SOURCES/libvirt-util-Publish-and-mock-virHostCPUGetMSRFromKVM.patch
  53. 43
      centos-9/SOURCES/libvirt-util-virGetSubIDs-do-not-limit-file-size.patch
  54. 79
      centos-9/SOURCES/libvirt-viriommufd-Set-IOMMU_OPTION_RLIMIT_MODE-only-when-running-privileged.patch
  55. 68
      centos-9/SOURCES/libvirt-virsh-Add-expand-cpu-features-option-for-domcapabilities.patch
  56. 75
      centos-9/SOURCES/libvirt-virsh-Add-supported-cpu-features-option-for-domcapabilities.patch
  57. 3
      centos-9/SOURCES/zfs-2.2.10.tar.gz
  58. 3
      centos-9/SOURCES/zfs-2.2.8.tar.gz
  59. 3
      centos-9/SOURCES/zfs-2.2.9.tar.gz
  60. 89
      centos-9/SPECS/libvirt.spec
  61. 4
      centos-9/SPECS/zfs-dkms.spec
  62. 5
      centos-9/SPECS/zfs.spec
  63. 91
      common.sh
  64. 29
      fedora-41/SOURCES/0001-virarptable-Properly-calculate-rtattr-length.patch
  65. 34
      fedora-41/SOURCES/0002-virarptable-Fix-check-for-message-length.patch
  66. 46
      fedora-41/SOURCES/0003-virarptable-End-parsing-earlier-in-case-of-NLMSG_DON.patch
  67. 315
      fedora-41/SOURCES/0004-util-use-a-single-flags-arg-for-virNetDevBandwidthSe.patch
  68. 185
      fedora-41/SOURCES/0005-util-make-it-optional-to-clear-existing-tc-qdiscs-fi.patch
  69. 98
      fedora-41/SOURCES/0006-util-put-the-command-that-adds-a-tx-filter-qdisc-int.patch
  70. 107
      fedora-41/SOURCES/0007-util-don-t-re-add-the-qdisc-used-for-tx-filters-if-i.patch
  71. 171
      fedora-41/SOURCES/0008-util-add-new-tc-layer-for-virFirewallCmd-objects.patch
  72. 687
      fedora-41/SOURCES/0009-network-add-tc-filter-rule-to-nftables-backend-to-fi.patch
  73. 51
      fedora-41/SOURCES/0010-network-permit-forward-mode-open-when-a-network-has-.patch
  74. 64
      fedora-41/SOURCES/0011-qemu-snapshot-delete-disk-image-only-if-parent-snaps.patch
  75. 3
      fedora-41/SOURCES/libvirt-10.6.0.tar.xz
  76. 3
      fedora-41/SOURCES/zfs-2.3.4.tar.gz
  77. 3
      fedora-41/SOURCES/zfs-2.3.5.tar.gz
  78. 3
      fedora-41/SOURCES/zfs-2.4.0.tar.gz
  79. 31
      fedora-42/SOURCES/0001-Fix-mocking-of-virQEMUCapsProbeHVF-function.patch
  80. 85
      fedora-42/SOURCES/0001-nss-Skip-empty-files-and-avoid-use-of-uninitialized-.patch
  81. 68
      fedora-42/SOURCES/0001-qemu-Be-more-forgiving-when-acquiring-QUERY-job-when.patch
  82. 94
      fedora-42/SOURCES/0001-storage-stop-hardcoding-paths-for-mkfs-mount-umount.patch
  83. 43
      fedora-42/SOURCES/0001-util-avoid-overflow-in-hextable-buffer.patch
  84. 58
      fedora-42/SOURCES/0001-util-stop-hardcoding-numad-path.patch
  85. 36
      fedora-42/SOURCES/0001-wireshark-Drop-needless-declaration-of-proto_registe.patch
  86. 47
      fedora-42/SOURCES/0002-wireshark-Switch-header-files-to-pragma-once.patch
  87. 81
      fedora-42/SOURCES/0003-wireshark-Move-WIRESHARK_VERSION-macro-definition.patch
  88. 133
      fedora-42/SOURCES/0004-wireshark-Fix-int-type-of-some-virNetMessageHeader-m.patch
  89. 46
      fedora-42/SOURCES/0005-wireshark-Don-t-special-case-retval-of-get_program_d.patch
  90. 68
      fedora-42/SOURCES/0006-wireshark-Introduce-and-use-vir_val_to_str.patch
  91. 165
      fedora-42/SOURCES/0007-wireshark-Don-t-leak-column-strings.patch
  92. 493
      fedora-42/SOURCES/0008-wireshark-Adapt-to-wireshark-4.6.0.patch
  93. 3
      fedora-42/SOURCES/libvirt-11.0.0.tar.xz
  94. 3
      fedora-42/SOURCES/zfs-2.3.4.tar.gz
  95. 3
      fedora-42/SOURCES/zfs-2.3.5.tar.gz
  96. 3
      fedora-42/SOURCES/zfs-2.4.0.tar.gz
  97. 3
      fedora-42/SOURCES/zfs-2.4.1.tar.gz
  98. 3
      fedora-42/SOURCES/zfs-2.4.2.tar.gz
  99. 3
      fedora-43/SOURCES/zfs-2.3.5.tar.gz
  100. 3
      fedora-43/SOURCES/zfs-2.4.0.tar.gz

2
.github/workflows/backport.yaml

@ -18,7 +18,7 @@ jobs:
steps:
# 1. Install pre-requisites
- name: Install pre-requisites
run: dnf install -y patch git git-lfs
run: dnf install -y patch git git-lfs jq
# 2. Checkout the repository
- name: Checkout repository

3
.github/workflows/copr-build.yaml

@ -8,6 +8,7 @@ on:
- fedora-*/SOURCES/**
- centos-*/SPECS/*.spec
- centos-*/SOURCES/**
- '!fedora-rawhide/**'
# Enables manual triggering of the workflow
workflow_dispatch:
@ -23,7 +24,7 @@ jobs:
steps:
# 1. Install pre-requisites
- name: Install copr-cli
run: dnf install -y copr-cli git git-lfs
run: dnf install -y copr-cli git git-lfs jq
# 2. Checkout the repository
- name: Checkout repository

45
.github/workflows/rawhide-backport.yaml

@ -0,0 +1,45 @@
name: Backport Packages for Fedora Rawhide (Daily)
# Every day at 02:00 UTC
on:
schedule:
- cron: '0 2 * * *'
# Enables manual triggering of the workflow
workflow_dispatch:
jobs:
update-packages-rawhide:
runs-on: ubuntu-latest
# Defines the Fedora container for this job
container:
image: fedora:latest
steps:
# 1. Install pre-requisites
- name: Install pre-requisites
run: dnf install -y patch git git-lfs jq
# 2. Checkout the repository
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: main
lfs: true
# We cannot use the default GITHUB_TOKEN as it is restricted and cannot
# trigger another workflow run, which is needed here to trigger the COPR build
token: ${{ secrets.COMMIT_TOKEN }}
# 2.5. Configure Git safe directory
- name: Configure Git safe directory
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
# 3. Run the update script for Fedora Rawhide only.
- name: Run update script for Fedora Rawhide (best effort)
run: ./update.sh fedora-rawhide
# 4. Push changes (if any)
- uses: stefanzweifel/git-auto-commit-action@v7
with:
commit_message: Backport packages from Fedora Rawhide
commit_author: Nicolas Massé <nicolas.masse@itix.fr>

38
.github/workflows/rawhide-copr-build.yaml

@ -0,0 +1,38 @@
name: Trigger COPR Build for Fedora Rawhide
on:
# Trigger on push, but only for fedora-rawhide SPECS and SOURCES changes
push:
paths:
- fedora-rawhide/SPECS/*.spec
- fedora-rawhide/SOURCES/**
# Enables manual triggering of the workflow
workflow_dispatch:
jobs:
build-copr-rawhide:
runs-on: ubuntu-latest
# Defines the Fedora container for this job
container:
image: fedora:latest
steps:
# 1. Install copr-cli
- name: Install copr-cli
run: dnf install -y copr-cli git git-lfs jq
# 2. Checkout the repository
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
lfs: true
# 3. Run the build script for Fedora Rawhide only.
- name: Run COPR build script for Fedora Rawhide (best effort)
run: ./build.sh fedora-rawhide
# Inject secrets into the container as environment variables
env:
COPR_CONFIG: ${{ secrets.COPR_CONFIG }}

13
build.sh

@ -2,6 +2,8 @@
set -Eeuo pipefail
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
if [ ! -f "$HOME/.config/copr" ] && [ -n "$COPR_CONFIG" ]; then
echo "Copr configuration file not found. Injecting from environment variable..."
mkdir -p "$HOME/.config"
@ -13,7 +15,14 @@ GIT_REPOSITORY="https://github.com/nmasse-itix/zfs-aarch64.git"
COPR_PROJECT="zfs-aarch64"
COPR_USERNAME="$(copr-cli whoami)"
for dist in centos-{9,10} fedora-{42,43}; do
if [ $# -gt 0 ]; then
dists=( "$@" )
else
echo "Computing a list of currently maintained versions of Fedora and CentOS Stream..."
dists=( $(get_all_remote_dists) )
fi
for dist in "${dists[@]}"; do
copr_release="${dist//centos/epel}"
echo "Building packages for $copr_release..."
for spec in $dist/SPECS/*.spec; do
@ -27,7 +36,7 @@ for dist in centos-{9,10} fedora-{42,43}; do
# Since the ZFS driver of libvirt is disabled since Fedora 43, we also build it for x86_64.
# And CentOS never shipped the Libvirt ZFS driver, so we build it for x86_64 as well.
if [[ "$package_name" == "libvirt" ]]; then
if [[ "$dist_name" == "fedora" && "$dist_version" -ge "43" || "$dist_name" == "centos" ]]; then
if [[ "$dist_name" == "fedora" && ( "$dist_version" == "rawhide" || "$dist_version" -ge "43" ) || "$dist_name" == "centos" ]]; then
copr_args+=( --chroot "$copr_release-x86_64" )
fi
fi

3
centos-10/SOURCES/libvirt-11.8.0.tar.xz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f7882fe65302bbcf804b573e0128c4fc6bfc52c9c3f44852a04de2391d858e34
size 10093332

3
centos-10/SOURCES/libvirt-11.9.0.tar.xz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:104f70ee591e72989d4f8c6caa79ed9dacd5dc84efdb0125b848afe544ad0c2d
size 10145112

3
centos-10/SOURCES/zfs-2.2.10.tar.gz

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:06bb2efe406454b398621db73dee9bac80e31b80ab0df662c4d57f5fca974b41
size 33883409

3
centos-10/SOURCES/zfs-2.2.8.tar.gz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ef669f8ba31b6998a97002d29eb079c8680e59fd2a9202fcb9ca7a9d9522459d
size 33857690

3
centos-10/SOURCES/zfs-2.2.9.tar.gz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a2a2b8ba8dcb1b73f82d416f2399315d7e2cb129711e945922e4688d46f32d9f
size 33879322

4
centos-10/SPECS/zfs-dkms.spec

@ -12,8 +12,8 @@
Name: %{module}-dkms
Version: 2.2.9
Release: 3%{?dist}
Version: 2.2.10
Release: 1%{?dist}
Summary: Kernel module(s) (dkms)
Group: System Environment/Kernel

5
centos-10/SPECS/zfs.spec

@ -90,8 +90,8 @@
%define __python_sitelib %(%{__python} -Esc "from distutils.sysconfig import get_python_lib; print(get_python_lib())" 2>/dev/null || %{__python} -Esc "import sysconfig; print(sysconfig.get_path('purelib'))")
Name: zfs
Version: 2.2.9
Release: 3%{?dist}
Version: 2.2.10
Release: 1%{?dist}
Summary: Commands to control the kernel modules and libraries
Group: System Environment/Kernel
@ -529,7 +529,6 @@ systemctl --system daemon-reload >/dev/null || true
%config(noreplace) %{_sysconfdir}/%{name}/zed.d/*
%config(noreplace) %{_sysconfdir}/%{name}/zpool.d/*
%config(noreplace) %{_sysconfdir}/%{name}/vdev_id.conf.*.example
%attr(440, root, root) %config(noreplace) %{_sysconfdir}/sudoers.d/*
%config(noreplace) %{_bashcompletiondir}/zfs
%config(noreplace) %{_bashcompletiondir}/zpool

3
centos-9/SOURCES/libvirt-11.8.0.tar.xz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f7882fe65302bbcf804b573e0128c4fc6bfc52c9c3f44852a04de2391d858e34
size 10093332

3
centos-9/SOURCES/libvirt-11.9.0.tar.xz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:104f70ee591e72989d4f8c6caa79ed9dacd5dc84efdb0125b848afe544ad0c2d
size 10145112

73
centos-9/SOURCES/libvirt-Fix-documentation-of-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES.patch

@ -0,0 +1,73 @@
From 7a8f13f443843e8903ab18d5917f6f8bc4192dd6 Mon Sep 17 00:00:00 2001
Message-ID: <7a8f13f443843e8903ab18d5917f6f8bc4192dd6.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Tue, 26 May 2026 15:38:59 +0200
Subject: [PATCH] Fix documentation of
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES
The flag is designed for expanding the CPU model used by host-model. But
the documentation was sometimes describing it as showing all CPU
features supported on the host, which is wrong as the host may support
features that would not be enabled in host-model.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 090183a7dc4a64cca83937eff9a4e93a45b4d712)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
docs/manpages/virsh.rst | 5 +++--
src/libvirt-domain.c | 6 +++---
tools/virsh-host.c | 2 +-
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 85fa6ab011..7169b6bc05 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -640,8 +640,9 @@ flagged as deprecated for the CPU model by the hypervisor. These
features will be paired with the "disable" policy.
The **--expand-cpu-features** option will cause the host-model CPU definition
-to contain all CPU features supported on the host including those implicitly
-enabled by the selected CPU model.
+to contain all required CPU features including those implicitly enabled by the
+selected CPU model. Without this flag features that are part of the CPU model
+itself will not be listed.
pool-capabilities
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 034f126dd5..e146fa7e82 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -12331,9 +12331,9 @@ virDomainSetUserPassword(virDomainPtr dom,
* passthrough and so on.
*
* If @flags includes VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES,
- * libvirt will explicitly list all CPU features (in host-model CPU definition)
- * that are supported on the host. Without this flag features that are part of
- * the CPU model itself will not be listed.
+ * libvirt will explicitly list all CPU features that will be enabled for
+ * host-model CPU mode. Without this flag features that are part of the CPU
+ * model itself will not be listed.
*
* Returns NULL in case of error or an XML string
* defining the capabilities.
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index dd98917fa8..5dbeb54ae5 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -120,7 +120,7 @@ static const vshCmdOptDef opts_domcapabilities[] = {
},
{.name = "expand-cpu-features",
.type = VSH_OT_BOOL,
- .help = N_("show all features in host CPU model"),
+ .help = N_("expand 'host-model' CPU to also show features enabled by the CPU model"),
},
{.name = NULL}
};
--
2.54.0

54
centos-9/SOURCES/libvirt-Introduce-EXPAND_CPU_FEATURES-flag-for-domain-capabilities.patch

@ -0,0 +1,54 @@
From 9644e7aceda1ca2b88d9eb699a274c5b4eafbda1 Mon Sep 17 00:00:00 2001
Message-ID: <9644e7aceda1ca2b88d9eb699a274c5b4eafbda1.1780571166.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 11 Mar 2026 11:31:06 +0100
Subject: [PATCH] Introduce EXPAND_CPU_FEATURES flag for domain capabilities
The new VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES flag for
virConnectGetDomainCapabilities can be used to request the host-model
CPU definition to include all supported features (normally only extra
features relative to the selected CPU model are listed).
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 8aa13d1b16b08feea37ecacc85540671e7995bb8)
https://issues.redhat.com/browse/RHEL-153653
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
include/libvirt/libvirt-domain.h | 2 ++
src/libvirt-domain.c | 5 +++++
2 files changed, 7 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 8e62bd23d4..1c5dbdc26e 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -1517,6 +1517,8 @@ int virDomainMigrateStartPostCopy(virDomainPtr domain,
typedef enum {
/* Report host model with deprecated features disabled. (Since: 11.0.0) */
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES = (1 << 0),
+ /* Report all host model CPU features. (Since: 12.2.0) */
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES = (1 << 1),
} virConnectGetDomainCapabilitiesFlags;
char * virConnectGetDomainCapabilities(virConnectPtr conn,
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index c7451fee05..034f126dd5 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -12330,6 +12330,11 @@ virDomainSetUserPassword(virDomainPtr dom,
* instance, if host, libvirt and qemu is capable of VFIO
* passthrough and so on.
*
+ * If @flags includes VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES,
+ * libvirt will explicitly list all CPU features (in host-model CPU definition)
+ * that are supported on the host. Without this flag features that are part of
+ * the CPU model itself will not be listed.
+ *
* Returns NULL in case of error or an XML string
* defining the capabilities.
*
--
2.54.0

59
centos-9/SOURCES/libvirt-Introduce-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES-flag.patch

@ -0,0 +1,59 @@
From f4588f45d48037050c88624e37f7b13e15138b0e Mon Sep 17 00:00:00 2001
Message-ID: <f4588f45d48037050c88624e37f7b13e15138b0e.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 29 May 2026 12:52:39 +0200
Subject: [PATCH] Introduce
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES flag
Some CPU features may be enabled explicitly, but should not
automatically become part of a host-model CPU. Users can now request
such features to be shown in the host-model CPU in domain capabilities
by VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES flag.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit e1efd79e837456d209115c536fc7e5f14abcbc63)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
include/libvirt/libvirt-domain.h | 3 +++
src/libvirt-domain.c | 8 ++++++++
2 files changed, 11 insertions(+)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 1c5dbdc26e..4d7c0099ef 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -1519,6 +1519,9 @@ typedef enum {
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES = (1 << 0),
/* Report all host model CPU features. (Since: 12.2.0) */
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES = (1 << 1),
+ /* Report all CPU features supported on the host, even those that will not
+ * be enabled by host-model CPU mode. (Since: 12.5.0) */
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES = (1 << 2),
} virConnectGetDomainCapabilitiesFlags;
char * virConnectGetDomainCapabilities(virConnectPtr conn,
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index e146fa7e82..0ae48654df 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -12335,6 +12335,14 @@ virDomainSetUserPassword(virDomainPtr dom,
* host-model CPU mode. Without this flag features that are part of the CPU
* model itself will not be listed.
*
+ * Adding VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES to @flags
+ * tells libvirt to update the host-model CPU definition with features that are
+ * supported on the host, but will not be enabled by default when starting a
+ * domain with host-model CPU. Use both
+ * VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES and
+ * VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES flags to get a
+ * complete list of features that can be enabled on the host.
+ *
* Returns NULL in case of error or an XML string
* defining the capabilities.
*
--
2.54.0

160
centos-9/SOURCES/libvirt-conf-Add-iommufd-fdgroup-support.patch

@ -0,0 +1,160 @@
From 99ca73f9c43c7a266cf65f0012a5350197d0f229 Mon Sep 17 00:00:00 2001
Message-ID: <99ca73f9c43c7a266cf65f0012a5350197d0f229.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 15:28:17 +0100
Subject: [PATCH] conf: Add iommufd fdgroup support
This will allow management applications running libvirt without
necessary permissions to pass FD for /dev/iommu with per-process
locked memory accounting enabled.
Kernel uses per-user locked memory accounting by default which may
cause error while starting multiple VMs with host devices using IOMMUFD.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 58875a6df679c5272f61028d33bf1380c51b0d5b)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
docs/formatdomain.rst | 8 +++++++-
src/conf/domain_conf.c | 6 ++++++
src/conf/domain_conf.h | 1 +
src/conf/domain_validate.c | 16 ++++++++++++++++
src/conf/schemas/domaincommon.rng | 3 +++
tests/genericxml2xmlindata/iommufd.xml | 2 +-
6 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 86b3bad903..225152e0f2 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -1368,7 +1368,7 @@ Host Device IOMMUFD
<domain>
...
- <iommufd enabled='yes'/>
+ <iommufd enabled='yes' fdgroup='iommu'/>
...
</domain>
@@ -1382,6 +1382,12 @@ Host Device IOMMUFD
This controls IOMMUFD usage for all host devices, each device can change this
global default by setting ``iommufd`` attribute for ``driver`` element.
+ Optional ``fdgroup`` attribute can be used together with
+ `virDomainFDAssociate <html/libvirt-libvirt-domain.html#virDomainFDAssociate>`__
+ to pass /dev/iommu FD instead of letting libvirt to open it. Caller is
+ responsible for setting per-process locked memory accounting otherwise
+ starting multiple VMs with host devices using IOMMUFD may fail.
+
Resource partitioning
---------------------
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 1e91561fea..cec0f88f0f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4192,6 +4192,8 @@ void virDomainDefFree(virDomainDef *def)
g_free(def->kvm_features);
g_free(def->tcg_features);
+ g_free(def->iommufd_fdgroup);
+
virBlkioDeviceArrayClear(def->blkio.devices,
def->blkio.ndevices);
g_free(def->blkio.devices);
@@ -19765,6 +19767,8 @@ virDomainDefIommufdParse(virDomainDef *def,
if (virXMLPropTristateBool(nodes[0], "enabled", VIR_XML_PROP_REQUIRED, &def->iommufd) < 0)
return -1;
+ def->iommufd_fdgroup = virXMLPropString(nodes[0], "fdgroup");
+
return 0;
}
@@ -27998,6 +28002,8 @@ virDomainDefIommufdFormat(virBuffer *buf,
virBufferAsprintf(&attrBuf, " enabled='%s'",
virTristateBoolTypeToString(def->iommufd));
+ virBufferEscapeString(&attrBuf, " fdgroup='%s'", def->iommufd_fdgroup);
+
virXMLFormatElement(buf, "iommufd", &attrBuf, NULL);
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index e12064a3ab..8c8c11c0cf 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3232,6 +3232,7 @@ struct _virDomainDef {
virDomainFeatureTCG *tcg_features;
virTristateBool iommufd;
+ char *iommufd_fdgroup;
bool tseg_specified;
unsigned long long tseg_size;
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 4558e7b210..3e6ba5e609 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -1995,6 +1995,19 @@ virDomainDefValidateThrottleGroups(const virDomainDef *def)
}
+static int
+virDomainDefValidateIommufd(const virDomainDef *def)
+{
+ if (def->iommufd == VIR_TRISTATE_BOOL_NO && def->iommufd_fdgroup) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Setting 'fdgroup' when 'iommufd' is disabled is not supported."));
+ return -1;
+ }
+
+ return 0;
+}
+
+
static int
virDomainDefValidateInternal(const virDomainDef *def,
virDomainXMLOption *xmlopt)
@@ -2056,6 +2069,9 @@ virDomainDefValidateInternal(const virDomainDef *def,
if (virDomainDefValidateThrottleGroups(def) < 0)
return -1;
+ if (virDomainDefValidateIommufd(def) < 0)
+ return -1;
+
return 0;
}
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 81b57a937a..9fde565d94 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -1353,6 +1353,9 @@
<attribute name="enabled">
<ref name="virYesNo"/>
</attribute>
+ <optional>
+ <attribute name="fdgroup"/>
+ </optional>
</element>
</define>
diff --git a/tests/genericxml2xmlindata/iommufd.xml b/tests/genericxml2xmlindata/iommufd.xml
index 63ea839383..10d59ca548 100644
--- a/tests/genericxml2xmlindata/iommufd.xml
+++ b/tests/genericxml2xmlindata/iommufd.xml
@@ -4,7 +4,7 @@
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
<vcpu placement='static'>1</vcpu>
- <iommufd enabled='yes'/>
+ <iommufd enabled='yes' fdgroup='iommu'/>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
--
2.54.0

218
centos-9/SOURCES/libvirt-conf-Introduce-domain-iommufd-element.patch

@ -0,0 +1,218 @@
From 28b77cb65fd0eedbd017d97d803256265ce3cbf4 Mon Sep 17 00:00:00 2001
Message-ID: <28b77cb65fd0eedbd017d97d803256265ce3cbf4.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 11:57:57 +0100
Subject: [PATCH] conf: Introduce domain iommufd element
In addition to configuring IOMMUFD for each host device add
configuration for the whole VM. This will be extended to add support for
passing FD to libvirt from management applications.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit c03b8f0804f648a2bbc2eb7e957f2f8821b8e167)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
docs/formatdomain.rst | 21 ++++++++++++
src/conf/domain_conf.c | 46 ++++++++++++++++++++++++++
src/conf/domain_conf.h | 2 ++
src/conf/schemas/domaincommon.rng | 12 +++++++
tests/genericxml2xmlindata/iommufd.xml | 18 ++++++++++
tests/genericxml2xmltest.c | 2 ++
6 files changed, 101 insertions(+)
create mode 100644 tests/genericxml2xmlindata/iommufd.xml
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 5ec9a41aac..86b3bad903 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -1361,6 +1361,27 @@ Block I/O Tuning
``write_iops_sec``
Write I/O operations per second limit. :since:`Since 1.2.2`
+Host Device IOMMUFD
+-------------------
+
+::
+
+ <domain>
+ ...
+ <iommufd enabled='yes'/>
+ ...
+ </domain>
+
+``iommufd``
+ :since:`Since 12.2.0 (QEMU/KVM only)` The optional ``iommufd`` element with
+ mandatory ``enabled`` attribute can be used to enable IOMMUFD backend for
+ VFIO host devices. This provides an interface to propagate DMA mappings to
+ kernel for assigned devices. Libvirt will open the /dev/iommu and VFIO device
+ cdev and pass associated file descriptors to QEMU.
+
+ This controls IOMMUFD usage for all host devices, each device can change this
+ global default by setting ``iommufd`` attribute for ``driver`` element.
+
Resource partitioning
---------------------
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 576a1bd79b..1e91561fea 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -19743,6 +19743,31 @@ virDomainDefControllersParse(virDomainDef *def,
return 0;
}
+static int
+virDomainDefIommufdParse(virDomainDef *def,
+ xmlXPathContextPtr ctxt)
+{
+ int n;
+ g_autofree xmlNodePtr *nodes = NULL;
+
+ if ((n = virXPathNodeSet("./iommufd", ctxt, &nodes)) < 0)
+ return -1;
+
+ if (n > 1) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("only one 'iommufd' element is supported"));
+ return -1;
+ }
+
+ if (n == 0)
+ return 0;
+
+ if (virXMLPropTristateBool(nodes[0], "enabled", VIR_XML_PROP_REQUIRED, &def->iommufd) < 0)
+ return -1;
+
+ return 0;
+}
+
static virDomainDef *
virDomainDefParseXML(xmlXPathContextPtr ctxt,
virDomainXMLOption *xmlopt,
@@ -19821,6 +19846,9 @@ virDomainDefParseXML(xmlXPathContextPtr ctxt,
!virDomainIOThreadIDArrayHasPin(def))
def->placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO;
+ if (virDomainDefIommufdParse(def, ctxt) < 0)
+ return NULL;
+
if ((n = virXPathNodeSet("./resource", ctxt, &nodes)) < 0)
return NULL;
@@ -27958,6 +27986,22 @@ virDomainHubDefFormat(virBuffer *buf,
}
+static void
+virDomainDefIommufdFormat(virBuffer *buf,
+ virDomainDef *def)
+{
+ g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
+
+ if (def->iommufd == VIR_TRISTATE_BOOL_ABSENT)
+ return;
+
+ virBufferAsprintf(&attrBuf, " enabled='%s'",
+ virTristateBoolTypeToString(def->iommufd));
+
+ virXMLFormatElement(buf, "iommufd", &attrBuf, NULL);
+}
+
+
static void
virDomainResourceDefFormat(virBuffer *buf,
virDomainResourceDef *def)
@@ -29482,6 +29526,8 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def,
if (virDomainNumatuneFormatXML(buf, def->numa) < 0)
return -1;
+ virDomainDefIommufdFormat(buf, def);
+
virDomainResourceDefFormat(buf, def->resource);
for (i = 0; i < def->nsysinfo; i++) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index f1c8478208..e12064a3ab 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3231,6 +3231,8 @@ struct _virDomainDef {
virTristateSwitch apic_eoi;
virDomainFeatureTCG *tcg_features;
+ virTristateBool iommufd;
+
bool tseg_specified;
unsigned long long tseg_size;
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index afdf7bfc1a..81b57a937a 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -1001,6 +1001,10 @@
<ref name="numatune"/>
</optional>
+ <optional>
+ <ref name="iommufd"/>
+ </optional>
+
<optional>
<ref name="respartition"/>
</optional>
@@ -1344,6 +1348,14 @@
</element>
</define>
+ <define name="iommufd">
+ <element name="iommufd">
+ <attribute name="enabled">
+ <ref name="virYesNo"/>
+ </attribute>
+ </element>
+ </define>
+
<define name="respartition">
<element name="resource">
<optional>
diff --git a/tests/genericxml2xmlindata/iommufd.xml b/tests/genericxml2xmlindata/iommufd.xml
new file mode 100644
index 0000000000..63ea839383
--- /dev/null
+++ b/tests/genericxml2xmlindata/iommufd.xml
@@ -0,0 +1,18 @@
+<domain type='kvm'>
+ <name>foo</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <iommufd enabled='yes'/>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ </devices>
+</domain>
diff --git a/tests/genericxml2xmltest.c b/tests/genericxml2xmltest.c
index 6757fc44de..6be694cac5 100644
--- a/tests/genericxml2xmltest.c
+++ b/tests/genericxml2xmltest.c
@@ -263,6 +263,8 @@ mymain(void)
DO_TEST("iothreadids");
+ DO_TEST("iommufd");
+
virObjectUnref(caps);
virObjectUnref(xmlopt);
--
2.54.0

330
centos-9/SOURCES/libvirt-conf-Move-and-rename-virStorageSourceFDTuple-object.patch

@ -0,0 +1,330 @@
From 15b1edcb2dca52b4d2276359c1eeaa97d66ac400 Mon Sep 17 00:00:00 2001
Message-ID: <15b1edcb2dca52b4d2276359c1eeaa97d66ac400.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 16:59:01 +0100
Subject: [PATCH] conf: Move and rename virStorageSourceFDTuple object
Associating FD can be used by other parts of VM so rename it to generic
virDomainFDTuple.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit f89e3dbce809f64246a8fe5ef0d05a63a28a05c0)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/conf/meson.build | 1 +
src/conf/storage_source_conf.c | 42 ---------------------------
src/conf/storage_source_conf.h | 24 ++--------------
src/conf/virdomainfd.c | 52 ++++++++++++++++++++++++++++++++++
src/conf/virdomainfd.h | 27 ++++++++++++++++++
src/libvirt_private.syms | 5 +++-
src/qemu/qemu_backup.c | 2 +-
src/qemu/qemu_domain.c | 2 +-
src/qemu/qemu_driver.c | 6 ++--
tests/testutilsqemu.c | 2 +-
10 files changed, 92 insertions(+), 71 deletions(-)
create mode 100644 src/conf/virdomainfd.c
create mode 100644 src/conf/virdomainfd.h
diff --git a/src/conf/meson.build b/src/conf/meson.build
index 5116c23fe3..6f95b23cce 100644
--- a/src/conf/meson.build
+++ b/src/conf/meson.build
@@ -20,6 +20,7 @@ domain_conf_sources = [
'numa_conf.c',
'snapshot_conf.c',
'virdomaincheckpointobjlist.c',
+ 'virdomainfd.c',
'virdomainjob.c',
'virdomainmomentobjlist.c',
'virdomainobjlist.c',
diff --git a/src/conf/storage_source_conf.c b/src/conf/storage_source_conf.c
index 24d4b0de6a..493b1411b3 100644
--- a/src/conf/storage_source_conf.c
+++ b/src/conf/storage_source_conf.c
@@ -1413,48 +1413,6 @@ virStorageSourceInitiatorClear(virStorageSourceInitiatorDef *initiator)
VIR_FREE(initiator->iqn);
}
-G_DEFINE_TYPE(virStorageSourceFDTuple, vir_storage_source_fd_tuple, G_TYPE_OBJECT);
-
-static void
-vir_storage_source_fd_tuple_init(virStorageSourceFDTuple *fdt G_GNUC_UNUSED)
-{
-}
-
-
-static void
-virStorageSourceFDTupleFinalize(GObject *object)
-{
- virStorageSourceFDTuple *fdt = VIR_STORAGE_SOURCE_FD_TUPLE(object);
- size_t i;
-
- if (!fdt)
- return;
-
- for (i = 0; i < fdt->nfds; i++)
- VIR_FORCE_CLOSE(fdt->fds[i]);
-
- g_free(fdt->fds);
- g_free(fdt->testfds);
- g_free(fdt->selinuxLabel);
- G_OBJECT_CLASS(vir_storage_source_fd_tuple_parent_class)->finalize(object);
-}
-
-
-static void
-vir_storage_source_fd_tuple_class_init(virStorageSourceFDTupleClass *klass)
-{
- GObjectClass *obj = G_OBJECT_CLASS(klass);
-
- obj->finalize = virStorageSourceFDTupleFinalize;
-}
-
-
-virStorageSourceFDTuple *
-virStorageSourceFDTupleNew(void)
-{
- return g_object_new(vir_storage_source_fd_tuple_get_type(), NULL);
-}
-
/**
* virStorageSourceNetworkProtocolPathSplit:
diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h
index 5a4b088eeb..b47313bae5 100644
--- a/src/conf/storage_source_conf.h
+++ b/src/conf/storage_source_conf.h
@@ -24,6 +24,7 @@
#include "storage_encryption_conf.h"
#include "virbitmap.h"
#include "virconftypes.h"
+#include "virdomainfd.h"
#include "virenum.h"
#include "virobject.h"
#include "virpci.h"
@@ -268,27 +269,6 @@ struct _virStorageSourceSlice {
void
virStorageSourceSliceFree(virStorageSourceSlice *slice);
-struct _virStorageSourceFDTuple {
- GObject parent;
- int *fds;
- size_t nfds;
- int *testfds; /* populated by tests to ensure stable FDs */
-
- bool writable;
- bool tryRestoreLabel;
-
- /* connection this FD tuple is associated with for auto-closing */
- virConnect *conn;
-
- /* original selinux label when we relabel the image */
- char *selinuxLabel;
-};
-G_DECLARE_FINAL_TYPE(virStorageSourceFDTuple, vir_storage_source_fd_tuple, VIR, STORAGE_SOURCE_FD_TUPLE, GObject);
-
-virStorageSourceFDTuple *
-virStorageSourceFDTupleNew(void);
-
-
typedef struct _virStorageSource virStorageSource;
/* Stores information related to a host resource. In the case of backing
@@ -441,7 +421,7 @@ struct _virStorageSource {
* one event for it */
bool thresholdEventWithIndex;
- virStorageSourceFDTuple *fdtuple;
+ virDomainFDTuple *fdtuple;
/* Setting 'seclabelSkipRemember' to true will cause the security driver to
* not remember the security label even if it otherwise were to be
diff --git a/src/conf/virdomainfd.c b/src/conf/virdomainfd.c
new file mode 100644
index 0000000000..13c3161e6a
--- /dev/null
+++ b/src/conf/virdomainfd.c
@@ -0,0 +1,52 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include <config.h>
+
+#include "virdomainfd.h"
+
+#include "virfile.h"
+
+G_DEFINE_TYPE(virDomainFDTuple, vir_domain_fd_tuple, G_TYPE_OBJECT);
+
+
+static void
+vir_domain_fd_tuple_init(virDomainFDTuple *fdt G_GNUC_UNUSED)
+{
+}
+
+
+static void
+virDomainFDTupleFinalize(GObject *object)
+{
+ virDomainFDTuple *fdt = VIR_DOMAIN_FD_TUPLE(object);
+ size_t i;
+
+ if (!fdt)
+ return;
+
+ for (i = 0; i < fdt->nfds; i++)
+ VIR_FORCE_CLOSE(fdt->fds[i]);
+
+ g_free(fdt->fds);
+ g_free(fdt->testfds);
+ g_free(fdt->selinuxLabel);
+ G_OBJECT_CLASS(vir_domain_fd_tuple_parent_class)->finalize(object);
+}
+
+
+static void
+vir_domain_fd_tuple_class_init(virDomainFDTupleClass *klass)
+{
+ GObjectClass *obj = G_OBJECT_CLASS(klass);
+
+ obj->finalize = virDomainFDTupleFinalize;
+}
+
+
+virDomainFDTuple *
+virDomainFDTupleNew(void)
+{
+ return g_object_new(vir_domain_fd_tuple_get_type(), NULL);
+}
diff --git a/src/conf/virdomainfd.h b/src/conf/virdomainfd.h
new file mode 100644
index 0000000000..0c0d475ed6
--- /dev/null
+++ b/src/conf/virdomainfd.h
@@ -0,0 +1,27 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#include "internal.h"
+
+struct _virDomainFDTuple {
+ GObject parent;
+ int *fds;
+ size_t nfds;
+ int *testfds; /* populated by tests to ensure stable FDs */
+
+ bool writable;
+ bool tryRestoreLabel;
+
+ /* connection this FD tuple is associated with for auto-closing */
+ virConnect *conn;
+
+ /* original selinux label when we relabel the image */
+ char *selinuxLabel;
+};
+G_DECLARE_FINAL_TYPE(virDomainFDTuple, vir_domain_fd_tuple, VIR, DOMAIN_FD_TUPLE, GObject);
+
+virDomainFDTuple *
+virDomainFDTupleNew(void);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index effe44fe57..386e757d81 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1177,7 +1177,6 @@ virStorageSourceChainHasManagedPR;
virStorageSourceChainHasNVMe;
virStorageSourceClear;
virStorageSourceCopy;
-virStorageSourceFDTupleNew;
virStorageSourceGetActualType;
virStorageSourceGetSecurityLabelDef;
virStorageSourceHasBacking;
@@ -1230,6 +1229,10 @@ virDomainCheckpointUpdateRelations;
virDomainListCheckpoints;
+# conf/virdomainfd.h
+virDomainFDTupleNew;
+
+
#conf/virdomainjob.h
virDomainAgentJobTypeToString;
virDomainAsyncJobTypeFromString;
diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
index c3566bcd57..eebf6cdc06 100644
--- a/src/qemu/qemu_backup.c
+++ b/src/qemu/qemu_backup.c
@@ -876,7 +876,7 @@ qemuBackupBegin(virDomainObj *vm,
priv->backup = g_steal_pointer(&def);
if (pull && priv->backup->server->fdgroup) {
- virStorageSourceFDTuple *fdt = NULL;
+ virDomainFDTuple *fdt = NULL;
VIR_AUTOCLOSE fdcopy = -1;
if (!(fdt = virHashLookup(priv->fds, priv->backup->server->fdgroup))) {
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index ccbfc8bac7..5c9f4831fd 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -9835,7 +9835,7 @@ qemuDomainPrepareStorageSourceFDs(virStorageSource *src,
{
qemuDomainStorageSourcePrivate *srcpriv = NULL;
virStorageType actualType = virStorageSourceGetActualType(src);
- virStorageSourceFDTuple *fdt = NULL;
+ virDomainFDTuple *fdt = NULL;
size_t i;
if (actualType != VIR_STORAGE_TYPE_FILE &&
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ecd19663ce..8db9cbb6a2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20241,7 +20241,7 @@ qemuDomainFDHashCloseConnect(virDomainObj *vm,
virConnectPtr conn)
{
qemuDomainObjPrivate *priv = QEMU_DOMAIN_PRIVATE(vm);
- virStorageSourceFDTuple *data;
+ virDomainFDTuple *data;
GHashTableIter htitr;
if (!priv->fds)
@@ -20265,7 +20265,7 @@ qemuDomainFDAssociate(virDomainPtr domain,
{
virDomainObj *vm = NULL;
qemuDomainObjPrivate *priv;
- g_autoptr(virStorageSourceFDTuple) new = NULL;
+ g_autoptr(virDomainFDTuple) new = NULL;
size_t i;
int ret = -1;
@@ -20283,7 +20283,7 @@ qemuDomainFDAssociate(virDomainPtr domain,
priv = vm->privateData;
- new = virStorageSourceFDTupleNew();
+ new = virDomainFDTupleNew();
new->nfds = nfds;
new->fds = g_new0(int, new->nfds);
for (i = 0; i < new->nfds; i++) {
diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c
index 78ec521266..fc51e0e3df 100644
--- a/tests/testutilsqemu.c
+++ b/tests/testutilsqemu.c
@@ -713,7 +713,7 @@ testQemuInfoSetArgs(testQemuInfo *info,
break;
case ARG_FD_GROUP: {
- virStorageSourceFDTuple *new = virStorageSourceFDTupleNew();
+ virDomainFDTuple *new = virDomainFDTupleNew();
const char *fdname = va_arg(argptr, char *);
VIR_AUTOCLOSE fakefd = open("/dev/zero", O_RDWR);
bool writable = va_arg(argptr, int);
--
2.54.0

113
centos-9/SOURCES/libvirt-conf-Parse-hyperv-features-even-for-host-model.patch

@ -0,0 +1,113 @@
From b60749c749a3312148c72471b99bd76469a6aff2 Mon Sep 17 00:00:00 2001
Message-ID: <b60749c749a3312148c72471b99bd76469a6aff2.1780571166.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 11 Feb 2026 10:16:28 +0100
Subject: [PATCH] conf: Parse hyperv features even for host-model
As it turns out, some users of the hyperv "host-model" mode might
want to override the hypervisor defaults. For instance disable a
feature that's on by default, or vice versa. Currently, this is
not possible because as soon as our XML parser sees the
"host-model" mode it exits early and skips parsing of individual
features (for "custom" mode). Well, do not return early and parse
the rest.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 380fb8939009a420f598175e63994a5bf197fd56)
Resolves: https://issues.redhat.com/browse/RHEL-151688
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
docs/formatdomain.rst | 3 +++
src/conf/domain_conf.c | 3 +--
src/conf/schemas/domaincommon.rng | 8 ++++----
tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml | 6 +++++-
tests/qemuxmlconfdata/hyperv-host-model.xml | 6 +++++-
5 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst
index 31232deb3c..5ec9a41aac 100644
--- a/docs/formatdomain.rst
+++ b/docs/formatdomain.rst
@@ -2197,6 +2197,9 @@ are:
enlightenments are supported by hypervisor and expands them on domain
startup into the live XML. In a sense, this is similar to ``host-model``
CPU mode (See `CPU model and topology`_). :since:`Since 11.9.0`
+ It is also possible to set features, like in ``custom`` mode. These are
+ then left untouched and no expansion is done for them. :since:`Since
+ 12.1.0`
The ``mode`` attribute can be omitted and will default to ``custom``.
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index df05d96f01..1f7b1ca340 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -17269,8 +17269,7 @@ virDomainFeaturesHyperVDefParse(virDomainDef *def,
def->features[VIR_DOMAIN_FEATURE_HYPERV] = mode;
- if (mode == VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH ||
- mode == VIR_DOMAIN_HYPERV_MODE_HOST_MODEL)
+ if (mode == VIR_DOMAIN_HYPERV_MODE_PASSTHROUGH)
return 0;
node = xmlFirstElementChild(node);
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index 441328a08e..afdf7bfc1a 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -8063,13 +8063,13 @@
<attribute name="mode">
<value>passthrough</value>
</attribute>
- <attribute name="mode">
- <value>host-model</value>
- </attribute>
<group>
<optional>
<attribute name="mode">
- <value>custom</value>
+ <choice>
+ <value>custom</value>
+ <value>host-model</value>
+ </choice>
</attribute>
</optional>
<interleave>
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
index 453a43b3c9..9535cee02a 100644
--- a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
+++ b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.xml
@@ -10,7 +10,11 @@
</os>
<features>
<acpi/>
- <hyperv mode='host-model'/>
+ <hyperv mode='host-model'>
+ <relaxed state='on'/>
+ <spinlocks state='on' retries='8192'/>
+ <xmm_input state='off'/>
+ </hyperv>
</features>
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>qemu64</model>
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.xml b/tests/qemuxmlconfdata/hyperv-host-model.xml
index fae00d86dd..473a41892d 100644
--- a/tests/qemuxmlconfdata/hyperv-host-model.xml
+++ b/tests/qemuxmlconfdata/hyperv-host-model.xml
@@ -10,7 +10,11 @@
</os>
<features>
<acpi/>
- <hyperv mode='host-model'/>
+ <hyperv mode='host-model'>
+ <relaxed state='on'/>
+ <spinlocks state='on' retries='8192'/>
+ <xmm_input state='off'/>
+ </hyperv>
</features>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
--
2.54.0

80
centos-9/SOURCES/libvirt-conf-Refactor-virHostdevIsPCIDevice.patch

@ -0,0 +1,80 @@
From 7af5a1f92b63d250922e04b56cae67bfb65fa4f4 Mon Sep 17 00:00:00 2001
Message-ID: <7af5a1f92b63d250922e04b56cae67bfb65fa4f4.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 11:47:21 +0100
Subject: [PATCH] conf: Refactor virHostdevIsPCIDevice
Future patches will need to check if the host device uses IOMMUFD or not
but we also need to keep a function that will check only if it is PCI device.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit d0afa0a842ce8a6dcb3f881d7dccdf5198f78fa7)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/conf/domain_conf.c | 34 +++++++++++++++++++++++++++++-----
1 file changed, 29 insertions(+), 5 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 35de8bab6b..59df028192 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32782,6 +32782,33 @@ virHostdevIsMdevDevice(const virDomainHostdevDef *hostdev)
}
+static bool
+virHostdevPCIDevHasIOMMUFD(const virDomainHostdevDef *hostdev)
+{
+ return hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO &&
+ hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES;
+}
+
+
+static bool
+virHostdevIsPCIDeviceImpl(const virDomainHostdevDef *hostdev,
+ virTristateBool iommufd)
+{
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ return false;
+
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ return false;
+
+ if (iommufd != VIR_TRISTATE_BOOL_ABSENT) {
+ bool hasIOMMUFD = iommufd == VIR_TRISTATE_BOOL_YES;
+ return hasIOMMUFD == virHostdevPCIDevHasIOMMUFD(hostdev);
+ }
+
+ return true;
+}
+
+
/**
* virHostdevIsPCIDevice:
* @hostdev: host device to check
@@ -32791,8 +32818,7 @@ virHostdevIsMdevDevice(const virDomainHostdevDef *hostdev)
bool
virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
{
- return hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
- hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
+ return virHostdevIsPCIDeviceImpl(hostdev, VIR_TRISTATE_BOOL_ABSENT);
}
@@ -32805,9 +32831,7 @@ virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
bool
virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev)
{
- return virHostdevIsPCIDevice(hostdev) &&
- hostdev->source.subsys.u.pci.driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO &&
- hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES;
+ return virHostdevIsPCIDeviceImpl(hostdev, VIR_TRISTATE_BOOL_YES);
}
--
2.54.0

158
centos-9/SOURCES/libvirt-cpu-Introduce-virCPUUpdateFeatures.patch

@ -0,0 +1,158 @@
From 353e7eb26cb922bd342c050273afbcc4ed4dd20e Mon Sep 17 00:00:00 2001
Message-ID: <353e7eb26cb922bd342c050273afbcc4ed4dd20e.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Mon, 25 May 2026 14:22:58 +0200
Subject: [PATCH] cpu: Introduce virCPUUpdateFeatures
This new API can be used to update an existing CPU definition with
features described by CPU data.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 6be1be4938338477bff14ff24c7ed2a05bc1dadc)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/cpu/cpu.c | 34 ++++++++++++++++++++++++++++++++++
src/cpu/cpu.h | 12 ++++++++++++
src/cpu/cpu_x86.c | 23 +++++++++++++++++++++++
src/libvirt_private.syms | 1 +
4 files changed, 70 insertions(+)
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index d81e620a1d..3e9affa1cd 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -1359,6 +1359,40 @@ virCPUGetCanonicalModel(virArch arch,
}
+/** virCPUUpdateFeatures:
+ *
+ * @arch: CPU architecture
+ * @cpu: CPU definition to update
+ * @cpuData: CPU data describing features
+ * @policy: to be used by the updated features
+ *
+ * Updates features described in @cpuData to use the specified @policy. Missing
+ * features will be automatically added to the CPU definition.
+ *
+ * Returns 0 on success, -1 otherwise.
+ */
+int
+virCPUUpdateFeatures(virArch arch,
+ virCPUDef *cpu,
+ virCPUData *cpuData,
+ virCPUFeaturePolicy policy)
+{
+ struct cpuArchDriver *driver;
+
+ VIR_DEBUG("arch=%s, cpu=%p, model=%s, policy=%s",
+ virArchToString(arch), cpu, NULLSTR(cpu->model),
+ virCPUFeaturePolicyTypeToString(policy));
+
+ if (!(driver = cpuGetSubDriver(arch)))
+ return -1;
+
+ if (!driver->updateFeatures)
+ return 0;
+
+ return driver->updateFeatures(cpu, cpuData, policy);
+}
+
+
/**
* virCPUArchIsSupported:
*
diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h
index 36fd123675..65711ac085 100644
--- a/src/cpu/cpu.h
+++ b/src/cpu/cpu.h
@@ -143,6 +143,11 @@ typedef int
typedef const char *
(*virCPUArchGetCanonicalModel)(const char *model);
+typedef int
+(*virCPUArchUpdateFeatures)(virCPUDef *cpu,
+ virCPUData *cpuData,
+ virCPUFeaturePolicy policy);
+
struct cpuArchDriver {
const char *name;
const virArch *arch;
@@ -172,6 +177,7 @@ struct cpuArchDriver {
virCPUArchDataGetHost dataGetHost;
virCPUArchGetCheckMode getCheckMode;
virCPUArchGetCanonicalModel getCanonicalModel;
+ virCPUArchUpdateFeatures updateFeatures;
};
@@ -332,6 +338,12 @@ const char *
virCPUGetCanonicalModel(virArch arch,
const char *model);
+int
+virCPUUpdateFeatures(virArch arch,
+ virCPUDef *cpu,
+ virCPUData *cpuData,
+ virCPUFeaturePolicy policy);
+
bool
virCPUArchIsSupported(virArch arch);
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index e5825fbb4d..6e860de458 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -3790,6 +3790,28 @@ virCPUx86GetCanonicalModel(const char *modelName)
}
+static int
+virCPUx86UpdateFeatures(virCPUDef *cpu,
+ virCPUData *cpuData,
+ virCPUFeaturePolicy policy)
+{
+ virCPUx86Data *data = &cpuData->data.x86;
+ virCPUx86Map *map;
+ size_t i;
+
+ if (!(map = virCPUx86GetMap()))
+ return -1;
+
+ for (i = 0; i < map->nfeatures; i++) {
+ virCPUx86Feature *feature = map->features[i];
+ if (x86DataIsSubset(data, &feature->data))
+ virCPUDefUpdateFeature(cpu, feature->name, policy);
+ }
+
+ return 0;
+}
+
+
struct cpuArchDriver cpuDriverX86 = {
.name = "x86",
.arch = archs,
@@ -3824,4 +3846,5 @@ struct cpuArchDriver cpuDriverX86 = {
#endif
.getCheckMode = virCPUx86GetCheckMode,
.getCanonicalModel = virCPUx86GetCanonicalModel,
+ .updateFeatures = virCPUx86UpdateFeatures,
};
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3eb6943440..4a0f9065fa 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1586,6 +1586,7 @@ virCPUGetVendorForModel;
virCPUProbeHost;
virCPUTranslate;
virCPUUpdate;
+virCPUUpdateFeatures;
virCPUUpdateLive;
virCPUValidateFeatures;
--
2.54.0

109
centos-9/SOURCES/libvirt-cpu_conf-Introduce-virCPUDefSortFeatures.patch

@ -0,0 +1,109 @@
From 6a2bd2d2e74d8c07266558c62d3fb724e677e256 Mon Sep 17 00:00:00 2001
Message-ID: <6a2bd2d2e74d8c07266558c62d3fb724e677e256.1780571166.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 29 May 2026 13:00:10 +0200
Subject: [PATCH] cpu_conf: Introduce virCPUDefSortFeatures
Separate the sorting code from virCPUExpandFeatures into a standalone
function.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 0900cc4f2dca2c17e8854330d45dffa4cc7952c4)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/conf/cpu_conf.c | 20 ++++++++++++++++++++
src/conf/cpu_conf.h | 3 +++
src/cpu/cpu.c | 15 +--------------
src/libvirt_private.syms | 1 +
4 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index 7aeedf64f5..f5a2004ee6 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -1277,3 +1277,23 @@ virCPUDefListFree(virCPUDef **cpus)
g_free(cpus);
}
+
+
+static int
+virCPUFeatureDefCompare(const void *p1,
+ const void *p2,
+ void *opaque G_GNUC_UNUSED)
+{
+ const virCPUFeatureDef *f1 = p1;
+ const virCPUFeatureDef *f2 = p2;
+
+ return strcmp(f1->name, f2->name);
+}
+
+
+void
+virCPUDefSortFeatures(virCPUDef *cpu)
+{
+ g_qsort_with_data(cpu->features, cpu->nfeatures, sizeof(*cpu->features),
+ virCPUFeatureDefCompare, NULL);
+}
diff --git a/src/conf/cpu_conf.h b/src/conf/cpu_conf.h
index cfb8f1a461..0cac1a1489 100644
--- a/src/conf/cpu_conf.h
+++ b/src/conf/cpu_conf.h
@@ -280,3 +280,6 @@ virCPUDefListParse(const char **xmlCPUs,
virCPUType cpuType);
void
virCPUDefListFree(virCPUDef **cpus);
+
+void
+virCPUDefSortFeatures(virCPUDef *cpu);
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 233686485d..d81e620a1d 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -1125,18 +1125,6 @@ virCPUConvertLegacy(virArch arch,
}
-static int
-virCPUFeatureCompare(const void *p1,
- const void *p2,
- void *opaque G_GNUC_UNUSED)
-{
- const virCPUFeatureDef *f1 = p1;
- const virCPUFeatureDef *f2 = p2;
-
- return strcmp(f1->name, f2->name);
-}
-
-
/**
* virCPUExpandFeatures:
*
@@ -1168,8 +1156,7 @@ virCPUExpandFeatures(virArch arch,
driver->expandFeatures(cpu) < 0)
return -1;
- g_qsort_with_data(cpu->features, cpu->nfeatures, sizeof(*cpu->features),
- virCPUFeatureCompare, NULL);
+ virCPUDefSortFeatures(cpu);
VIR_DEBUG("nfeatures=%zu", cpu->nfeatures);
return 0;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d2563e587a..1733286bad 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -118,6 +118,7 @@ virCPUDefNew;
virCPUDefParseXML;
virCPUDefParseXMLString;
virCPUDefRef;
+virCPUDefSortFeatures;
virCPUDefStealModel;
virCPUDefUpdateFeature;
virCPUMaxPhysAddrModeTypeFromString;
--
2.54.0

109
centos-9/SOURCES/libvirt-cpu_x86-Introduce-virCPUx86DataAddMSR.patch

@ -0,0 +1,109 @@
From d34cc77ac31f6df5195dad6b53d5aed00bda7dd7 Mon Sep 17 00:00:00 2001
Message-ID: <d34cc77ac31f6df5195dad6b53d5aed00bda7dd7.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Mon, 25 May 2026 13:17:47 +0200
Subject: [PATCH] cpu_x86: Introduce virCPUx86DataAddMSR
This just makes the relevant part of virCPUx86GetHost reusable in other
places.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit a8952076d8e5062a2fac08e11597ad47871c2236)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/cpu/cpu_x86.c | 40 ++++++++++++++++++++++++++++------------
src/cpu/cpu_x86.h | 4 ++++
src/libvirt_private.syms | 1 +
3 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 0f7eb8f48b..e5825fbb4d 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -2912,18 +2912,8 @@ virCPUx86GetHost(virCPUDef *cpu,
/* This is best effort since there might be no way to read the MSR
* when we are not running as root. */
for (i = 0; i < nmsrs; i++) {
- if (virHostCPUGetMSR(msrs[i], &msr) == 0) {
- virCPUx86DataItem item = {
- .type = VIR_CPU_X86_DATA_MSR,
- .data.msr = {
- .index = msrs[i],
- .eax = msr & 0xffffffff,
- .edx = msr >> 32,
- },
- };
-
- virCPUx86DataAdd(cpuData, &item);
- }
+ if (virHostCPUGetMSR(msrs[i], &msr) == 0)
+ virCPUx86DataAddMSR(cpuData, msrs[i], msr);
}
ret = x86DecodeCPUData(cpu, cpuData, models);
@@ -3461,6 +3451,32 @@ virCPUx86DataAdd(virCPUData *cpuData,
}
+/**
+ * virCPUx86DataAddMSR:
+ * @cpuData: CPU data to update
+ * @index: MSR index
+ * @value: content of the @index MSR
+ *
+ * Adds the specified MSR content to CPU data.
+ */
+void
+virCPUx86DataAddMSR(virCPUData *cpuData,
+ uint32_t index,
+ uint64_t value)
+{
+ virCPUx86DataItem item = {
+ .type = VIR_CPU_X86_DATA_MSR,
+ .data.msr = {
+ .index = index,
+ .eax = value & 0xffffffff,
+ .edx = value >> 32,
+ },
+ };
+
+ virCPUx86DataAdd(cpuData, &item);
+}
+
+
void
virCPUx86DataSetSignature(virCPUData *cpuData,
unsigned int family,
diff --git a/src/cpu/cpu_x86.h b/src/cpu/cpu_x86.h
index 2cd965fea4..bbc2a16447 100644
--- a/src/cpu/cpu_x86.h
+++ b/src/cpu/cpu_x86.h
@@ -28,6 +28,10 @@ extern struct cpuArchDriver cpuDriverX86;
void virCPUx86DataAdd(virCPUData *cpuData,
const virCPUx86DataItem *cpuid);
+void virCPUx86DataAddMSR(virCPUData *cpuData,
+ uint32_t index,
+ uint64_t value);
+
void virCPUx86DataSetSignature(virCPUData *cpuData,
unsigned int family,
unsigned int model,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3eca15f066..3eb6943440 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1592,6 +1592,7 @@ virCPUValidateFeatures;
# cpu/cpu_x86.h
virCPUx86DataAdd;
+virCPUx86DataAddMSR;
virCPUx86DataGetSignature;
virCPUx86DataSetSignature;
virCPUx86DataSetVendor;
--
2.54.0

34
centos-9/SOURCES/libvirt-docs-Clarify-host-model-description-in-domain-capabilities.patch

@ -0,0 +1,34 @@
From 4c6ab1e34ea5e57dc0f9880f178354538adf55f7 Mon Sep 17 00:00:00 2001
Message-ID: <4c6ab1e34ea5e57dc0f9880f178354538adf55f7.1780571166.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 11 Mar 2026 12:13:45 +0100
Subject: [PATCH] docs: Clarify host-model description in domain capabilities
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 0b54c9d535b9b7c832ff8422dca28c84eb75ed2e)
https://issues.redhat.com/browse/RHEL-153653
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
docs/formatdomaincaps.rst | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst
index 6ba7f84f96..add550a4a5 100644
--- a/docs/formatdomaincaps.rst
+++ b/docs/formatdomaincaps.rst
@@ -244,6 +244,10 @@ more details about it:
reports physical address size of the host CPU if this value is available and
applicable for the requested domain type. This is useful for computing
baseline CPU definition which should be compatible with several hosts.
+ Consistently with all other CPU definitions used by libvirt, features
+ implicitly enabled by the selected CPU model (in ``model`` sub element) are
+ not listed. Use ``--expand-cpu-features`` virsh option or the equivalent API
+ flag to request all supported features to be listed in the CPU definition.
``custom``
The ``mode`` element contains a list of supported CPU models, each described
by a dedicated ``model`` element. The ``usable`` attribute specifies whether
--
2.54.0

24245
centos-9/SOURCES/libvirt-domaincapstest-Test-EXPAND_CPU_FEATURES-flag.patch

File diff suppressed because it is too large

22680
centos-9/SOURCES/libvirt-domaincapstest-Test-SUPPORTED_CPU_FEATURES-flag.patch

File diff suppressed because it is too large

45
centos-9/SOURCES/libvirt-hypervisor-Call-virWaitForDevices-after-detaching-host-devices.patch

@ -0,0 +1,45 @@
From b338719eb9908c7dfd493d5ab4a1b0bcc2258d9b Mon Sep 17 00:00:00 2001
Message-ID: <b338719eb9908c7dfd493d5ab4a1b0bcc2258d9b.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Thu, 26 Mar 2026 14:32:36 +0100
Subject: [PATCH] hypervisor: Call virWaitForDevices() after detaching host
devices
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On systems with selinux enabled starting a VM with managed host device
using IOMMUFD backend can run into race-condition where both libvirt and
udev are setting selinux label on /dev/vfio/devices/vfioX device. If
udev is the last one to set selinux label starting VM fails with:
error: internal error: QEMU unexpectedly closed the monitor (vm='test'): 2026-03-26T15:47:36.620422Z qemu-kvm: -device {"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"20","bus":"pci.7","addr":"0x0"}: vfio hostdev0: Failed to add fd 20 to KVM VFIO device: Invalid argument
We need to wait for udev to finish processing all events.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit b96ea4db3aabac4790d6e1d53e2f309f5e73efae)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/hypervisor/virhostdev.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c
index 43155ceb6c..981ca4cd20 100644
--- a/src/hypervisor/virhostdev.c
+++ b/src/hypervisor/virhostdev.c
@@ -782,6 +782,9 @@ virHostdevPreparePCIDevicesImpl(virHostdevManager *mgr,
}
}
+ /* Step 2.5: Wait for udev to handle all events for devices. */
+ virWaitForDevices();
+
/* At this point, all devices are attached to the stub driver and have
* been marked as inactive */
--
2.54.0

98
centos-9/SOURCES/libvirt-hypervisor-Fix-virHostdevNeedsVFIO-detection.patch

@ -0,0 +1,98 @@
From 2f8eef47f391248abf5253c6836520100d5d49c1 Mon Sep 17 00:00:00 2001
Message-ID: <2f8eef47f391248abf5253c6836520100d5d49c1.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 11:57:43 +0100
Subject: [PATCH] hypervisor: Fix virHostdevNeedsVFIO detection
Function virHostdevNeedsVFIO is used only in QEMU to figure out if the
host device needs access to /dev/vfio/vfio, for PCI host devices that is
true only if libvirt is not using IOMMUFD.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit ffa8020d3665f7ff27c6b82e88d3a93674155c8d)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/conf/domain_conf.c | 13 +++++++++++++
src/conf/domain_conf.h | 3 +++
src/hypervisor/virhostdev.c | 9 ++++++++-
src/libvirt_private.syms | 1 +
4 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 59df028192..99d2a0aa53 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32835,6 +32835,19 @@ virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev)
}
+/**
+ * virHostdevIsPCIDeviceWithIOMMUFD:
+ * @hostdev: host device to check
+ *
+ * Returns true if @hostdev is a PCI device with IOMMUFD disabled, false otherwise.
+ */
+bool
+virHostdevIsPCIDeviceWithoutIOMMUFD(const virDomainHostdevDef *hostdev)
+{
+ return virHostdevIsPCIDeviceImpl(hostdev, VIR_TRISTATE_BOOL_NO);
+}
+
+
static void
virDomainObjGetMessagesIOErrorsSrc(virStorageSource *src,
const char *diskdst,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 69a8e79c6d..8f5780ee4c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4719,6 +4719,9 @@ virHostdevIsPCIDevice(const virDomainHostdevDef *hostdev)
bool
virHostdevIsPCIDeviceWithIOMMUFD(const virDomainHostdevDef *hostdev)
ATTRIBUTE_NONNULL(1);
+bool
+virHostdevIsPCIDeviceWithoutIOMMUFD(const virDomainHostdevDef *hostdev)
+ ATTRIBUTE_NONNULL(1);
void
virDomainObjGetMessagesIOErrorsChain(virStorageSource *src,
diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c
index 7d7df4418d..43155ceb6c 100644
--- a/src/hypervisor/virhostdev.c
+++ b/src/hypervisor/virhostdev.c
@@ -2510,10 +2510,17 @@ virHostdevUpdateActiveNVMeDevices(virHostdevManager *hostdev_mgr,
goto cleanup;
}
+/**
+ * virHostdevNeedsVFIO:
+ * @hostdev: host device to check
+ *
+ * Returns true if using the @hostdev requires access to /dev/vfio/vfio,
+ * otherwise false.
+ */
bool
virHostdevNeedsVFIO(const virDomainHostdevDef *hostdev)
{
- return virHostdevIsPCIDevice(hostdev) ||
+ return virHostdevIsPCIDeviceWithoutIOMMUFD(hostdev) ||
virHostdevIsMdevDevice(hostdev);
}
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 386e757d81..ea1e2d8586 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -814,6 +814,7 @@ virDomainQemuMonitorEventStateRegisterID;
virHostdevIsMdevDevice;
virHostdevIsPCIDevice;
virHostdevIsPCIDeviceWithIOMMUFD;
+virHostdevIsPCIDeviceWithoutIOMMUFD;
virHostdevIsSCSIDevice;
--
2.54.0

51
centos-9/SOURCES/libvirt-qemu-Expand-call-to-qemuDomainNeedsVFIO.patch

@ -0,0 +1,51 @@
From 5512f4ffa8f4ea8a4afd354e4592b69dc5c39c61 Mon Sep 17 00:00:00 2001
Message-ID: <5512f4ffa8f4ea8a4afd354e4592b69dc5c39c61.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 12:52:05 +0100
Subject: [PATCH] qemu: Expand call to qemuDomainNeedsVFIO
The function qemuDomainNeedsVFIO() was originally used by other parts
of qemu code to figure out if the VM needs /dev/vfio/vfio.
Later it was also used by code calculating locked memory limit for all
architectures, and after that change again and used only for PPC64.
Now it needs to be changed again due to IOMMUFD support, the
/dev/vfio/vfio device is used by QEMU only if IOMMUFD is not used
but for accounting we still need consider all PCI host devices
because if IOMMUFD is used it still requires increasing locked
memory limit.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit c89b2bf1a80e3261bd18cdb352be1ffce9f4639e)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_domain.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 5c9f4831fd..57f18a02b6 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8259,8 +8259,14 @@ getPPC64MemLockLimitBytes(virDomainDef *def)
passthroughLimit = maxMemory +
128 * (1ULL<<30) / 512 * nPCIHostBridges +
8192;
- } else if (qemuDomainNeedsVFIO(def) || virDomainDefHasVDPANet(def)) {
- /* For regular (non-NVLink2 present) VFIO passthrough, the value
+ } else if (virDomainDefHasPCIHostdev(def) ||
+ virDomainDefHasMdevHostdev(def) ||
+ virDomainDefHasNVMeDisk(def) ||
+ virDomainDefHasVDPANet(def)) {
+ /* Not using qemuDomainNeedsVFIO() as that doesn't take PCI host
+ * devices with IOMMFD into account.
+ *
+ * For regular (non-NVLink2 present) VFIO passthrough, the value
* of passthroughLimit is:
*
* passthroughLimit := max( 2 GiB * #PHBs, (c)
--
2.54.0

245
centos-9/SOURCES/libvirt-qemu-Fix-IOMMUFD-and-VFIO-security-labels.patch

@ -0,0 +1,245 @@
From 39dd90e66f661ce816592c1ee7cfd5bba54ea6f5 Mon Sep 17 00:00:00 2001
Message-ID: <39dd90e66f661ce816592c1ee7cfd5bba54ea6f5.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 27 Feb 2026 17:55:34 +0100
Subject: [PATCH] qemu: Fix IOMMUFD and VFIO security labels
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When IOMMUFD support was introduced it incorrectly tried to label
`/dev/iommu` and `/dev/vfio/devices/vfioX` but they are not added to
QEMU namespace because libvirt opens FDs and passes these FDs to QEMU.
We need to label these FDs instead.
Fixes: 7d2f91f9cb572ab95d0916bdd1a46dd198874529
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 03f2672ab4eff8ee01410c9acba6288bfb4fa231)
Resolves: https://redhat.atlassian.net/browse/RHEL-159902
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_hotplug.c | 2 +-
src/qemu/qemu_process.c | 16 ++++++++++++----
src/qemu/qemu_process.h | 3 ++-
src/security/security_apparmor.c | 12 ------------
src/security/security_dac.c | 27 ---------------------------
src/security/security_selinux.c | 23 -----------------------
6 files changed, 15 insertions(+), 68 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 845f42bf20..994cc749f6 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1621,7 +1621,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
}
if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
- if (qemuProcessOpenVfioDeviceFd(hostdev) < 0)
+ if (qemuProcessOpenVfioDeviceFd(vm, hostdev) < 0)
goto error;
if (!priv->iommufdState) {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 29601683a0..0a69063a4b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7691,13 +7691,16 @@ int
qemuProcessOpenIommuFd(virDomainObj *vm)
{
qemuDomainObjPrivate *priv = vm->privateData;
- int iommufd;
+ VIR_AUTOCLOSE iommufd = -1;
VIR_DEBUG("Opening IOMMU FD for domain %s", vm->def->name);
if ((iommufd = virIOMMUFDOpenDevice()) < 0)
return -1;
+ if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0)
+ return -1;
+
priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd);
return 0;
@@ -7712,16 +7715,21 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
* Returns: 0 on success, -1 on failure
*/
int
-qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev)
+qemuProcessOpenVfioDeviceFd(virDomainObj *vm,
+ virDomainHostdevDef *hostdev)
{
+ qemuDomainObjPrivate *priv = vm->privateData;
qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev);
virDomainHostdevSubsysPCI *pci = &hostdev->source.subsys.u.pci;
g_autofree char *name = g_strdup_printf("hostdev-%s-fd", hostdev->info->alias);
- int vfioDeviceFd;
+ VIR_AUTOCLOSE vfioDeviceFd = -1;
if ((vfioDeviceFd = virPCIDeviceOpenVfioFd(&pci->addr)) < 0)
return -1;
+ if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, vfioDeviceFd) < 0)
+ return -1;
+
hostdevPriv->vfioDeviceFd = qemuFDPassDirectNew(name, &vfioDeviceFd);
return 0;
@@ -7739,7 +7747,7 @@ qemuProcessPrepareHostHostdev(virDomainObj *vm)
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
/* Open VFIO device FD */
- if (qemuProcessOpenVfioDeviceFd(hostdev) < 0)
+ if (qemuProcessOpenVfioDeviceFd(vm, hostdev) < 0)
return -1;
}
break;
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 1023b7cb25..dc16622ed9 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -136,7 +136,8 @@ int qemuProcessPrepareHostBackendChardevHotplug(virDomainObj *vm,
int qemuProcessOpenIommuFd(virDomainObj *vm);
-int qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev);
+int qemuProcessOpenVfioDeviceFd(virDomainObj *vm,
+ virDomainHostdevDef *hostdev);
int qemuProcessPrepareHost(virQEMUDriver *driver,
virDomainObj *vm,
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 1c3496893c..40f13ec1a5 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -45,7 +45,6 @@
#include "virstring.h"
#include "virscsi.h"
#include "virmdev.h"
-#include "viriommufd.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
@@ -856,17 +855,6 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
if (AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr) < 0)
return -1;
- } else {
- g_autofree char *vfiofdDev = NULL;
-
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
- return -1;
-
- if (AppArmorSetSecurityPCILabel(pci, vfiofdDev, ptr) < 0)
- return -1;
-
- if (AppArmorSetSecurityPCILabel(pci, VIR_IOMMU_DEV_PATH, ptr) < 0)
- return -1;
}
} else {
if (virPCIDeviceFileIterate(pci, AppArmorSetSecurityPCILabel, ptr) < 0)
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 2a4c7f6a3c..d8cf117fc4 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -41,7 +41,6 @@
#include "virscsivhost.h"
#include "virstring.h"
#include "virutil.h"
-#include "viriommufd.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
@@ -1295,17 +1294,6 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
&cbdata) < 0) {
return -1;
}
- } else {
- g_autofree char *vfiofdDev = NULL;
-
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
- return -1;
-
- if (virSecurityDACSetHostdevLabelHelper(vfiofdDev, false, &cbdata) < 0)
- return -1;
-
- if (virSecurityDACSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &cbdata) < 0)
- return -1;
}
} else {
if (virPCIDeviceFileIterate(pci,
@@ -1476,21 +1464,6 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
vfioGroupDev, false) < 0) {
return -1;
}
- } else {
- g_autofree char *vfiofdDev = NULL;
-
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
- return -1;
-
- if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
- vfiofdDev, false) < 0) {
- return -1;
- }
-
- if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
- VIR_IOMMU_DEV_PATH, false) < 0) {
- return -1;
- }
}
} else {
if (virPCIDeviceFileIterate(pci, virSecurityDACRestorePCILabel, mgr) < 0)
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 96ca59a7a4..0fa50630f7 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -41,7 +41,6 @@
#include "virconf.h"
#include "virtpm.h"
#include "virstring.h"
-#include "viriommufd.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
@@ -2267,17 +2266,6 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
&data) < 0) {
return -1;
}
- } else {
- g_autofree char *vfiofdDev = NULL;
-
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
- return -1;
-
- if (virSecuritySELinuxSetHostdevLabelHelper(vfiofdDev, false, &data) < 0)
- return -1;
-
- if (virSecuritySELinuxSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &data) < 0)
- return -1;
}
} else {
if (virPCIDeviceFileIterate(pci, virSecuritySELinuxSetPCILabel, &data) < 0)
@@ -2519,17 +2507,6 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
if (virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false, false) < 0)
return -1;
- } else {
- g_autofree char *vfiofdDev = NULL;
-
- if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
- return -1;
-
- if (virSecuritySELinuxRestoreFileLabel(mgr, vfiofdDev, false, false) < 0)
- return -1;
-
- if (virSecuritySELinuxRestoreFileLabel(mgr, VIR_IOMMU_DEV_PATH, false, false) < 0)
- return -1;
}
} else {
if (virPCIDeviceFileIterate(pci, virSecuritySELinuxRestorePCILabel, mgr) < 0)
--
2.54.0

60
centos-9/SOURCES/libvirt-qemu-Fix-job-handling-when-domain-dies-in-post-copy-migration.patch

@ -0,0 +1,60 @@
From 0c8a23f5f3e063b35b890d5538e5497f51d1095c Mon Sep 17 00:00:00 2001
Message-ID: <0c8a23f5f3e063b35b890d5538e5497f51d1095c.1780571166.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Mon, 23 Feb 2026 16:23:10 +0100
Subject: [PATCH] qemu: Fix job handling when domain dies in post-copy
migration
When a domain is in post-copy migration phase, we need to keep the job
active if something fails to protect the domain from changes.
Unfortunately, there is a race between migration code and
qemuProcessStop that can cause the job to stay active even when the
domain is gone and thus preventing the domain from being started again
(until virtqemud is restarted). The race is caused by unlocking the vm
object when calling virConnectUnregisterCloseCallback. While the domain
is unlocked qemuProcessStop can finish its work and the domain may no
longer be active when we get the lock back. The post-copy path does not
properly check if a domain is still active.
Instead of adding the virDomainObjIsActive check in all places where
this could happen, we can add it in virDomainObjIsPostcopy and
virDomainObjIsFailedPostcopy and let the code take the pre-copy cleanup
path. Clearly an inactive domain can never be in (failed) post-copy
migration.
https://issues.redhat.com/browse/RHEL-145179
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 3d1e6d92de784e5c9d2a5e4bc18829c92278343a)
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/conf/domain_conf.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 1f7b1ca340..35de8bab6b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30493,6 +30493,9 @@ bool
virDomainObjIsFailedPostcopy(virDomainObj *dom,
virDomainJobObj *job)
{
+ if (!virDomainObjIsActive(dom))
+ return false;
+
if (job && job->asyncPaused &&
(job->asyncJob == VIR_ASYNC_JOB_MIGRATION_IN ||
job->asyncJob == VIR_ASYNC_JOB_MIGRATION_OUT))
@@ -30509,6 +30512,9 @@ bool
virDomainObjIsPostcopy(virDomainObj *dom,
virDomainJobObj *job)
{
+ if (!virDomainObjIsActive(dom))
+ return false;
+
if (virDomainObjIsFailedPostcopy(dom, job))
return true;
--
2.54.0

47
centos-9/SOURCES/libvirt-qemu-Implement-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES.patch

@ -0,0 +1,47 @@
From eccea5104691012040f130ee0d400c2cc0b174f7 Mon Sep 17 00:00:00 2001
Message-ID: <eccea5104691012040f130ee0d400c2cc0b174f7.1780571166.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 11 Mar 2026 12:12:40 +0100
Subject: [PATCH] qemu: Implement
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 3215fee34967c49f37a965154879fc5860293cac)
https://issues.redhat.com/browse/RHEL-153653
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_driver.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f3e7410f9e..ecd19663ce 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16720,7 +16720,8 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
virDomainVirtType virttype;
g_autoptr(virDomainCaps) domCaps = NULL;
- virCheckFlags(VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES,
+ virCheckFlags(VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES |
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES,
NULL);
if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0)
@@ -16746,6 +16747,12 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
VIR_CPU_FEATURE_DISABLE);
}
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES) {
+ virCPUDef *cpu = domCaps->cpu.hostModel;
+ if (cpu && virCPUExpandFeatures(arch, cpu) < 0)
+ return NULL;
+ }
+
return virDomainCapsFormat(domCaps);
}
--
2.54.0

127
centos-9/SOURCES/libvirt-qemu-Implement-iommufd-fdgroup.patch

@ -0,0 +1,127 @@
From 8cdc3bb132898c37fe17762aba7dabb59819ce0a Mon Sep 17 00:00:00 2001
Message-ID: <8cdc3bb132898c37fe17762aba7dabb59819ce0a.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 16 Mar 2026 15:29:32 +0100
Subject: [PATCH] qemu: Implement iommufd fdgroup
When fdgroup is used for iommufd we will start QEMU with -object iommufd
even if the VM has no host device. When virDomainFDAssociate() is used
the FD libvirt is holding is closed with connection.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 0a83b28795f0c18592f9d842927528f0676cc56d)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_command.c | 4 +++-
src/qemu/qemu_hotplug.c | 4 ++--
src/qemu/qemu_process.c | 47 ++++++++++++++++++++++++++++++++++++++---
3 files changed, 49 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 23e799de3c..db72407ecc 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5360,8 +5360,10 @@ qemuBuildIOMMUFDCommandLine(virCommand *cmd,
qemuDomainObjPrivate *priv = vm->privateData;
g_autoptr(virJSONValue) props = NULL;
- if (!virDomainDefHasPCIHostdevWithIOMMUFD(def))
+ if (!virDomainDefHasPCIHostdevWithIOMMUFD(def) &&
+ !def->iommufd_fdgroup) {
return 0;
+ }
qemuFDPassDirectTransferCommand(priv->iommufd, cmd);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 25fe699bb3..8944062aa4 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1624,7 +1624,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriver *driver,
if (qemuProcessOpenVfioDeviceFd(vm, hostdev) < 0)
goto error;
- if (!priv->iommufdState) {
+ if (!priv->iommufdState && !vm->def->iommufd_fdgroup) {
if (qemuProcessOpenIommuFd(vm) < 0)
goto error;
@@ -5031,7 +5031,7 @@ qemuDomainRemoveHostDevice(virQEMUDriver *driver,
}
}
- if (priv->iommufdState &&
+ if (priv->iommufdState && !vm->def->iommufd_fdgroup &&
!virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) {
qemuDomainObjEnterMonitor(vm);
ignore_value(qemuMonitorDelObject(priv->mon, "iommufd0", false));
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index d13bce8fcf..e4746374f6 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7706,6 +7706,44 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
return 0;
}
+/**
+ * qemuProcessGetPassedIommuFd:
+ * @vm: domain object
+ *
+ * Find passed FD via virDomainFDAssociate() API for the VM.
+ *
+ * Returns: 0 on success, -1 on failure
+ */
+static int
+qemuProcessGetPassedIommuFd(virDomainObj *vm)
+{
+ qemuDomainObjPrivate *priv = vm->privateData;
+ virDomainFDTuple *fdt = virHashLookup(priv->fds, vm->def->iommufd_fdgroup);
+ VIR_AUTOCLOSE iommufd = -1;
+
+ if (!fdt) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("file descriptor group '%1$s' was not associated with the domain"),
+ vm->def->iommufd_fdgroup);
+ return -1;
+ }
+
+ if (fdt->nfds != 1) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("Only one file descriptor needs to be associated with iommufd"));
+ return -1;
+ }
+
+ iommufd = dup(fdt->fds[0]);
+
+ if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0)
+ return -1;
+
+ priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd);
+
+ return 0;
+}
+
/**
* qemuProcessOpenVfioDeviceFd:
* @hostdev: host device definition
@@ -7761,9 +7799,12 @@ qemuProcessPrepareHostHostdev(virDomainObj *vm)
}
/* Open IOMMU FD */
- if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def) &&
- qemuProcessOpenIommuFd(vm) < 0) {
- return -1;
+ if (vm->def->iommufd_fdgroup) {
+ if (qemuProcessGetPassedIommuFd(vm) < 0)
+ return -1;
+ } else if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) {
+ if (qemuProcessOpenIommuFd(vm) < 0)
+ return -1;
}
return 0;
--
2.54.0

119
centos-9/SOURCES/libvirt-qemu-Implement-iommufd.patch

@ -0,0 +1,119 @@
From e52edf2ed7f3e1e379fb85ae0c0870113912c9d6 Mon Sep 17 00:00:00 2001
Message-ID: <e52edf2ed7f3e1e379fb85ae0c0870113912c9d6.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 17:59:01 +0100
Subject: [PATCH] qemu: Implement iommufd
Ideally this should be done in qemuDomainHostdevDefPostParse but that
would require a lot of refactoring mainly due to how interface backed by
hostdev works.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit fc516031ed865f78d590068424ada19a941046ba)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_domain.c | 12 +++++++++---
src/qemu/qemu_domain.h | 3 ++-
src/qemu/qemu_hotplug.c | 2 +-
src/qemu/qemu_process.c | 4 ++--
4 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index a61939aa15..495cbd4f7d 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -10120,10 +10120,12 @@ qemuDomainPrepareHostdevSCSI(virDomainHostdevDef *hostdev,
static int
-qemuDomainPrepareHostdevPCI(virDomainHostdevDef *hostdev,
+qemuDomainPrepareHostdevPCI(const virDomainDef *def,
+ virDomainHostdevDef *hostdev,
virQEMUCaps *qemuCaps)
{
virDeviceHostdevPCIDriverName *driverName = &hostdev->source.subsys.u.pci.driver.name;
+ virDomainHostdevSubsysPCI *pcisrc = &hostdev->source.subsys.u.pci;
/* assign defaults for hostdev passthrough */
switch (*driverName) {
@@ -10160,12 +10162,16 @@ qemuDomainPrepareHostdevPCI(virDomainHostdevDef *hostdev,
return -1;
}
+ if (pcisrc->driver.iommufd == VIR_TRISTATE_BOOL_ABSENT)
+ pcisrc->driver.iommufd = def->iommufd;
+
return 0;
}
int
-qemuDomainPrepareHostdev(virDomainHostdevDef *hostdev,
+qemuDomainPrepareHostdev(const virDomainDef *def,
+ virDomainHostdevDef *hostdev,
qemuDomainObjPrivate *priv)
{
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
@@ -10175,7 +10181,7 @@ qemuDomainPrepareHostdev(virDomainHostdevDef *hostdev,
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
return qemuDomainPrepareHostdevSCSI(hostdev, priv);
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
- return qemuDomainPrepareHostdevPCI(hostdev, priv->qemuCaps);
+ return qemuDomainPrepareHostdevPCI(def, hostdev, priv->qemuCaps);
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 62c5252b9f..8cd221062c 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1048,7 +1048,8 @@ qemuDomainDiskCachemodeFlags(virDomainDiskCache cachemode,
bool *noflush);
int
-qemuDomainPrepareHostdev(virDomainHostdevDef *hostdev,
+qemuDomainPrepareHostdev(const virDomainDef *def,
+ virDomainHostdevDef *hostdev,
qemuDomainObjPrivate *priv);
char * qemuDomainGetManagedPRSocketPath(qemuDomainObjPrivate *priv);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 994cc749f6..25fe699bb3 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2900,7 +2900,7 @@ qemuDomainAttachHostDevice(virQEMUDriver *driver,
return -1;
}
- if (qemuDomainPrepareHostdev(hostdev, vm->privateData) < 0)
+ if (qemuDomainPrepareHostdev(vm->def, hostdev, vm->privateData) < 0)
return -1;
switch (hostdev->source.subsys.type) {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 9b8b378b1f..d13bce8fcf 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6050,7 +6050,7 @@ qemuProcessPrepareDomainNetwork(virDomainObj *vm)
/* For hostdev present in qemuProcessPrepareDomain() phase this was
* done already, but this code runs after that, so we have to call
* it ourselves. */
- if (qemuDomainPrepareHostdev(hostdev, priv) < 0)
+ if (qemuDomainPrepareHostdev(def, hostdev, priv) < 0)
return -1;
virDomainHostdevInsert(def, hostdev);
@@ -6838,7 +6838,7 @@ qemuProcessPrepareDomainHostdevs(virDomainObj *vm,
for (i = 0; i < vm->def->nhostdevs; i++) {
virDomainHostdevDef *hostdev = vm->def->hostdevs[i];
- if (qemuDomainPrepareHostdev(hostdev, priv) < 0)
+ if (qemuDomainPrepareHostdev(vm->def, hostdev, priv) < 0)
return -1;
}
--
2.54.0

196
centos-9/SOURCES/libvirt-qemu-Move-domain-caps-flags-handling-to-virQEMUCapsFillDomainCPUHostModel.patch

@ -0,0 +1,196 @@
From 9ec1c8fc52cd3150712f5ada134e070fbdabb7bb Mon Sep 17 00:00:00 2001
Message-ID: <9ec1c8fc52cd3150712f5ada134e070fbdabb7bb.1780571166.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Thu, 21 May 2026 12:36:48 +0200
Subject: [PATCH] qemu: Move domain caps flags handling to
virQEMUCapsFillDomainCPUHostModel
We will need to generate the capabilities in a different way based on
the flags.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit b4d3572198848e6a2886352e1a48b46afa37bec1)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 34 ++++++++++++++++++++++++----------
src/qemu/qemu_capabilities.h | 3 ++-
src/qemu/qemu_conf.c | 6 ++++--
src/qemu/qemu_conf.h | 3 ++-
src/qemu/qemu_driver.c | 15 ++-------------
tests/domaincapstest.c | 2 +-
6 files changed, 35 insertions(+), 28 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 0b32296cc8..c17b55420d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -6584,14 +6584,26 @@ virQEMUCapsFillDomainCPUMaximum(virDomainCaps *domCaps)
static void
virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
- virDomainCaps *domCaps)
+ virDomainCaps *domCaps,
+ unsigned int flags)
{
- virCPUDef *cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
- VIR_QEMU_CAPS_HOST_CPU_REPORTED);
+ virQEMUCapsHostCPUType cpuType = VIR_QEMU_CAPS_HOST_CPU_REPORTED;
+ virCPUDef *cpu;
- domCaps->cpu.hostModel = virCPUDefCopy(cpu);
- domCaps->cpu.hostModel->addr = virQEMUCapsGetHostPhysAddr(qemuCaps,
- domCaps->virttype);
+ cpu = virCPUDefCopy(virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
+ cpuType));
+
+ cpu->addr = virQEMUCapsGetHostPhysAddr(qemuCaps, domCaps->virttype);
+
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES) {
+ virQEMUCapsUpdateCPUDeprecatedFeatures(qemuCaps, domCaps->virttype,
+ cpu, VIR_CPU_FEATURE_DISABLE);
+ }
+
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES)
+ virCPUExpandFeatures(domCaps->arch, cpu);
+
+ domCaps->cpu.hostModel = cpu;
}
@@ -6616,7 +6628,8 @@ virQEMUCapsFillDomainCPUCustom(virQEMUCaps *qemuCaps,
static void
virQEMUCapsFillDomainCPUCaps(virQEMUCaps *qemuCaps,
virArch hostarch,
- virDomainCaps *domCaps)
+ virDomainCaps *domCaps,
+ unsigned int flags)
{
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
VIR_CPU_MODE_HOST_PASSTHROUGH,
@@ -6633,7 +6646,7 @@ virQEMUCapsFillDomainCPUCaps(virQEMUCaps *qemuCaps,
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
VIR_CPU_MODE_HOST_MODEL,
domCaps->machine)) {
- virQEMUCapsFillDomainCPUHostModel(qemuCaps, domCaps);
+ virQEMUCapsFillDomainCPUHostModel(qemuCaps, domCaps, flags);
}
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
@@ -7263,7 +7276,8 @@ virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg,
virQEMUCaps *qemuCaps,
virArch hostarch,
virDomainCaps *domCaps,
- bool privileged)
+ bool privileged,
+ unsigned int flags)
{
virDomainCapsOS *os = &domCaps->os;
virDomainCapsDeviceDisk *disk = &domCaps->disk;
@@ -7305,7 +7319,7 @@ virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg,
firmwares, nfirmwares) < 0)
return -1;
- virQEMUCapsFillDomainCPUCaps(qemuCaps, hostarch, domCaps);
+ virQEMUCapsFillDomainCPUCaps(qemuCaps, hostarch, domCaps, flags);
virQEMUCapsFillDomainMemoryBackingCaps(qemuCaps, memoryBacking);
virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps, domCaps->machine, disk);
virQEMUCapsFillDomainDeviceGraphicsCaps(cfg, qemuCaps, graphics);
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index f7c8680f94..bc3ecbb89f 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -896,7 +896,8 @@ int virQEMUCapsFillDomainCaps(virQEMUDriverConfig *cfg,
virQEMUCaps *qemuCaps,
virArch hostarch,
virDomainCaps *domCaps,
- bool privileged);
+ bool privileged,
+ unsigned int flags);
void virQEMUCapsFillDomainMemoryBackingCaps(virQEMUCaps *qemuCaps,
virDomainCapsMemoryBacking *memoryBacking);
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 242955200a..5e40635871 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1708,7 +1708,8 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriver *driver,
virQEMUCaps *qemuCaps,
const char *machine,
virArch arch,
- virDomainVirtType virttype)
+ virDomainVirtType virttype,
+ unsigned int flags)
{
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
g_autoptr(virDomainCaps) domCaps = NULL;
@@ -1742,7 +1743,8 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriver *driver,
qemuCaps,
driver->hostarch,
domCaps,
- driver->privileged) < 0)
+ driver->privileged,
+ flags) < 0)
return NULL;
return g_steal_pointer(&domCaps);
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index edb65c99f4..36d7808e10 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -375,7 +375,8 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriver *driver,
virQEMUCaps *qemuCaps,
const char *machine,
virArch arch,
- virDomainVirtType virttype);
+ virDomainVirtType virttype,
+ unsigned int flags);
int qemuDriverAllocateID(virQEMUDriver *driver);
virDomainXMLOption *virQEMUDriverCreateXMLConf(virQEMUDriver *driver,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8db9cbb6a2..0a61f97666 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16738,21 +16738,10 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
if (!(domCaps = virQEMUDriverGetDomainCapabilities(driver,
qemuCaps, machine,
- arch, virttype)))
+ arch, virttype,
+ flags)))
return NULL;
- if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES) {
- virQEMUCapsUpdateCPUDeprecatedFeatures(qemuCaps, virttype,
- domCaps->cpu.hostModel,
- VIR_CPU_FEATURE_DISABLE);
- }
-
- if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES) {
- virCPUDef *cpu = domCaps->cpu.hostModel;
- if (cpu && virCPUExpandFeatures(arch, cpu) < 0)
- return NULL;
- }
-
return virDomainCapsFormat(domCaps);
}
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
index 5b2fc80f0a..f2248c2435 100644
--- a/tests/domaincapstest.c
+++ b/tests/domaincapstest.c
@@ -101,7 +101,7 @@ fillQemuCaps(virDomainCaps *domCaps,
if (virQEMUCapsFillDomainCaps(cfg,
qemuCaps, domCaps->arch, domCaps,
- false) < 0)
+ false, 0) < 0)
return -1;
/* As of f05b6a918e28 we are expecting to see OVMF_CODE.fd file which
--
2.54.0

107
centos-9/SOURCES/libvirt-qemu-Update-qemuDomainNeedsVFIO-to-ignore-PCI-hostdev-with-IOMMUFD.patch

@ -0,0 +1,107 @@
From 84c12b67bed448ae5129e3b7c18b52fa397cf217 Mon Sep 17 00:00:00 2001
Message-ID: <84c12b67bed448ae5129e3b7c18b52fa397cf217.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Wed, 18 Mar 2026 13:10:37 +0100
Subject: [PATCH] qemu: Update qemuDomainNeedsVFIO to ignore PCI hostdev with
IOMMUFD
This function is used to figure out if VM needs access to /dev/vfio/vfio.
In case of PCI host devices that is true only if IOMMUFD is not enabled.
This fixes error when hotplugging PCI host device with IOMMUFD disabled
to a VM that already has PCI host device with IOMMIFD enabled:
Could not open '/dev/vfio/vfio': No such file or directory
The function is used in this case to check if /dev/vfio/vfio was already
made available to QEMU or not.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit d1fb5cf127d7681fa6c27e5b163ef410132aea49)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/conf/domain_conf.c | 14 ++++++++++++++
src/conf/domain_conf.h | 3 +++
src/libvirt_private.syms | 1 +
src/qemu/qemu_domain.c | 9 ++++++++-
4 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 99d2a0aa53..576a1bd79b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -32520,6 +32520,20 @@ virDomainDefHasPCIHostdevWithIOMMUFD(const virDomainDef *def)
}
+bool
+virDomainDefHasPCIHostdevWithoutIOMMUFD(const virDomainDef *def)
+{
+ size_t i;
+
+ for (i = 0; i < def->nhostdevs; i++) {
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(def->hostdevs[i]))
+ return true;
+ }
+
+ return false;
+}
+
+
bool
virDomainDefHasMdevHostdev(const virDomainDef *def)
{
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 8f5780ee4c..f1c8478208 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -4658,6 +4658,9 @@ virDomainDefHasPCIHostdev(const virDomainDef *def);
bool
virDomainDefHasPCIHostdevWithIOMMUFD(const virDomainDef *def);
+bool
+virDomainDefHasPCIHostdevWithoutIOMMUFD(const virDomainDef *def);
+
bool
virDomainDefHasMdevHostdev(const virDomainDef *def);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index ea1e2d8586..d2563e587a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -349,6 +349,7 @@ virDomainDefHasOldStyleROUEFI;
virDomainDefHasOldStyleUEFI;
virDomainDefHasPCIHostdev;
virDomainDefHasPCIHostdevWithIOMMUFD;
+virDomainDefHasPCIHostdevWithoutIOMMUFD;
virDomainDefHasTimer;
virDomainDefHasUSB;
virDomainDefHasVcpusOffline;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 57f18a02b6..a61939aa15 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -9284,10 +9284,17 @@ qemuDomainSupportsVideoVga(const virDomainVideoDef *video,
}
+/**
+ * qemuDomainNeedsVFIO:
+ * @def: domain definition to check
+ *
+ * Check the domain definition to figure out if QEMU needs access
+ * to /dev/vfio/vfio. It's not required if IOMMUFD is used.
+ */
bool
qemuDomainNeedsVFIO(const virDomainDef *def)
{
- return virDomainDefHasPCIHostdev(def) ||
+ return virDomainDefHasPCIHostdevWithoutIOMMUFD(def) ||
virDomainDefHasMdevHostdev(def) ||
virDomainDefHasNVMeDisk(def);
}
--
2.54.0

59
centos-9/SOURCES/libvirt-qemu-Wire-up-new-hyperv-host-model-mode-behavior.patch

@ -0,0 +1,59 @@
From dbaf42b6deae0149f88a3be8fbf52a5e94eb799d Mon Sep 17 00:00:00 2001
Message-ID: <dbaf42b6deae0149f88a3be8fbf52a5e94eb799d.1780571166.git.jdenemar@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Wed, 11 Feb 2026 10:16:34 +0100
Subject: [PATCH] qemu: Wire up new hyperv host-model mode behavior
Since some hyperv features might be already enabled/disabled when
entering qemuProcessEnableDomainFeatures() only those which are
not set in domain XML (i.e. are VIR_TRISTATE_SWITCH_ABSENT)
should be modified. Furthermore, some features are not a simple
on/off switch, but a number or a string even. Well, that doesn't
matter really as the logic for setting them is the same: only set
their value iff they are not already set.
Resolves: https://issues.redhat.com/browse/RHEL-148219
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 11057abfd13f6aad15f9821235b66c68e6211af6)
Resolves: https://issues.redhat.com/browse/RHEL-151688
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---
src/qemu/qemu_process.c | 8 +++++++-
.../qemuxmlconfdata/hyperv-host-model.x86_64-latest.args | 2 +-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 1aff3a277b..29601683a0 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6964,7 +6964,13 @@ qemuProcessEnableDomainFeatures(virDomainObj *vm)
if (!VIR_DOMAIN_CAPS_ENUM_IS_SET(hv->features, i))
continue;
- vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ON;
+ if (vm->def->hyperv.features[i] == VIR_TRISTATE_SWITCH_ABSENT) {
+ vm->def->hyperv.features[i] = VIR_TRISTATE_SWITCH_ON;
+ } else {
+ /* if the user provided already config for this we skip the
+ * auto-population code */
+ continue;
+ }
if (i == VIR_DOMAIN_HYPERV_SPINLOCKS) {
if (hv->spinlocks != 0) {
diff --git a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
index 58502ff51e..d1f2326da1 100644
--- a/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
+++ b/tests/qemuxmlconfdata/hyperv-host-model.x86_64-latest.args
@@ -12,7 +12,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \
-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \
-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=on \
-accel tcg \
--cpu 'qemu64,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0xfff,hv-vpindex=on,hv-runtime=on,hv-synic=on,hv-stimer=on,hv-stimer-direct=on,hv-reset=on,hv-vendor-id=Linux KVM Hv,hv-frequencies=on,hv-reenlightenment=on,hv-tlbflush=on,hv-tlbflush-direct=on,hv-tlbflush-ext=on,hv-ipi=on,hv-avic=on,hv-emsr-bitmap=on,hv-xmm-input=on' \
+-cpu 'qemu64,hv-time=on,hv-relaxed=on,hv-vapic=on,hv-spinlocks=0x2000,hv-vpindex=on,hv-runtime=on,hv-synic=on,hv-stimer=on,hv-stimer-direct=on,hv-reset=on,hv-vendor-id=Linux KVM Hv,hv-frequencies=on,hv-reenlightenment=on,hv-tlbflush=on,hv-tlbflush-direct=on,hv-tlbflush-ext=on,hv-ipi=on,hv-avic=on,hv-emsr-bitmap=on' \
-m size=219136k \
-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}' \
-overcommit mem-lock=off \
--
2.54.0

46
centos-9/SOURCES/libvirt-qemuMigrationSrcBeginPhase-Don-t-call-qemuBlockNodesEnsureActive-with-offline-VM.patch

@ -0,0 +1,46 @@
From 3e6b8f45de2cef2a8f08f84d62915b3cbaa050de Mon Sep 17 00:00:00 2001
Message-ID: <3e6b8f45de2cef2a8f08f84d62915b3cbaa050de.1780571166.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 18 Mar 2026 08:54:16 +0100
Subject: [PATCH] qemuMigrationSrcBeginPhase: Don't call
'qemuBlockNodesEnsureActive' with offline VM
Commits 7b5566ce67b18a and f879d5f40385358 ( v11.8.0-92-gf879d5f403 )
moved around code for re-activating block backends after migration.
While previously it was done when migration failed now we do it when we
need qemu to do some block operations.
'qemuBlockNodesEnsureActive' is thus called also when 'VIR_MIGRATE_OFFLINE'
is used. This doesn't cause failure similar to previous patch only due
to a conincidence as 'qemuCaps' wasn't initialized yet and thus we
assume that QEMU doesn't support 'blockdev-set-active' and skip all
monitor code.
Make the code more robust and explicit by calling
'qemuBlockNodesEnsureActive' only on active VMs during migration.
Fixes: 7b5566ce67b18a2bebe68fdb07e046f25185f8d3
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 4537c0b8708851136b8246b1869c6008a56240ae)
https://redhat.atlassian.net/browse/RHEL-173433
---
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 1fd9b1dd55..2b3f464fa6 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2868,7 +2868,8 @@ qemuMigrationSrcBeginPhase(virQEMUDriver *driver,
vm->newDef && !qemuDomainVcpuHotplugIsInOrder(vm->newDef)))
cookieFlags |= QEMU_MIGRATION_COOKIE_CPU_HOTPLUG;
- if (qemuBlockNodesEnsureActive(vm, vm->job->asyncJob) < 0)
+ if (virDomainObjIsActive(vm) &&
+ qemuBlockNodesEnsureActive(vm, vm->job->asyncJob) < 0)
return NULL;
return qemuMigrationSrcBeginXML(vm, xmlin,
--
2.54.0

45
centos-9/SOURCES/libvirt-qemuMigrationSrcBeginXML-Don-t-call-qemuMigrationSrcBeginPhaseBlockDirtyBitmaps-with-offline-VM.patch

@ -0,0 +1,45 @@
From f875d6f1e560dd9d73e373d576f2c784f6f8cb4c Mon Sep 17 00:00:00 2001
Message-ID: <f875d6f1e560dd9d73e373d576f2c784f6f8cb4c.1780571166.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 23 Mar 2026 22:39:58 +0100
Subject: [PATCH] qemuMigrationSrcBeginXML: Don't call
'qemuMigrationSrcBeginPhaseBlockDirtyBitmaps' with offline VM
Commit a4f610ff3fe190058f1 made the call to
'qemuMigrationSrcBeginPhaseBlockDirtyBitmaps' inside
'qemuMigrationSrcBeginXML' unconditional. This unfortunately means that
it was called also with 'VIR_MIGRATE_OFFLINE'.
Attempting to enter the monitor in such case results in an error:
error: operation failed: domain is no longer running
Restrict the call only to non-offline migration.
Fixes: a4f610ff3fe190058f18baea18b095d0bc69441b
Resolves: https://redhat.atlassian.net/browse/RHEL-156800
Closes: https://gitlab.com/libvirt/libvirt/-/work_items/865
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 59fde80f39567101010e7ba4dece4fd68b50090d)
https://redhat.atlassian.net/browse/RHEL-173433
---
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 2a4df1191d..1fd9b1dd55 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2689,7 +2689,8 @@ qemuMigrationSrcBeginXML(virDomainObj *vm,
if (!(mig = qemuMigrationCookieNew(vm->def, priv->origname)))
return NULL;
- if (qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(mig, vm) < 0)
+ if (!(flags & VIR_MIGRATE_OFFLINE) &&
+ qemuMigrationSrcBeginPhaseBlockDirtyBitmaps(mig, vm) < 0)
return NULL;
if (qemuMigrationCookieFormat(mig, driver, vm,
--
2.54.0

3806
centos-9/SOURCES/libvirt-qemu_capabilities-Always-sort-features-in-host-model-CPU.patch

File diff suppressed because it is too large

158
centos-9/SOURCES/libvirt-qemu_capabilities-Cache-expanded-CPU.patch

@ -0,0 +1,158 @@
From fba9c200834d8d31ed34e632470563a0074fe528 Mon Sep 17 00:00:00 2001
Message-ID: <fba9c200834d8d31ed34e632470563a0074fe528.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Thu, 21 May 2026 17:55:28 +0200
Subject: [PATCH] qemu_capabilities: Cache expanded CPU
When probing host model CPU we already expand it to get a list of all
CPU features. Let's store the expanded CPU definition in virQEMUCaps and
copy it to domain capabilities when requested by the
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES flag instead of
expanding the CPU over and over on each request.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 312000a739aebaa9de655bb1f6a539326ea8783d)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 39 ++++++++++++++++++++++++++----------
src/qemu/qemu_capabilities.h | 3 +++
2 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2e8f220abc..555723cafb 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -788,6 +788,9 @@ struct _virQEMUCapsHostCPUData {
unsigned int physAddrSize;
/* Host CPU definition reported in domain capabilities. */
virCPUDef *reported;
+ /* Expanded host CPU definition with features that are implicitly enabled
+ * by the selected CPU model. */
+ virCPUDef *expanded;
/* Migratable host CPU definition used for updating guest CPU. */
virCPUDef *migratable;
/* CPU definition with features detected by libvirt using virCPUGetHost
@@ -1962,6 +1965,9 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUData *dst,
if (src->reported)
dst->reported = virCPUDefCopy(src->reported);
+ if (src->expanded)
+ dst->expanded = virCPUDefCopy(src->expanded);
+
if (src->migratable)
dst->migratable = virCPUDefCopy(src->migratable);
@@ -1975,6 +1981,7 @@ virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUData *cpuData)
{
qemuMonitorCPUModelInfoFree(cpuData->info);
virCPUDefFree(cpuData->reported);
+ virCPUDefFree(cpuData->expanded);
virCPUDefFree(cpuData->migratable);
virCPUDefFree(cpuData->full);
@@ -2301,6 +2308,9 @@ virQEMUCapsGetHostModel(virQEMUCaps *qemuCaps,
/* 'full' is non-NULL only if we have data from both QEMU and
* virCPUGetHost */
return cpuData->full ? cpuData->full : cpuData->reported;
+
+ case VIR_QEMU_CAPS_HOST_CPU_EXPANDED:
+ return cpuData->expanded;
}
return NULL;
@@ -2312,6 +2322,7 @@ virQEMUCapsSetHostModel(virQEMUCaps *qemuCaps,
virDomainVirtType type,
unsigned int physAddrSize,
virCPUDef *reported,
+ virCPUDef *expanded,
virCPUDef *migratable,
virCPUDef *full)
{
@@ -2320,6 +2331,7 @@ virQEMUCapsSetHostModel(virQEMUCaps *qemuCaps,
cpuData = &virQEMUCapsGetAccel(qemuCaps, type)->hostCPU;
cpuData->physAddrSize = physAddrSize;
cpuData->reported = reported;
+ cpuData->expanded = expanded;
cpuData->migratable = migratable;
cpuData->full = full;
}
@@ -4123,16 +4135,18 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
virCPUDefCopyModelFilter(cpu, hostCPU, true, virQEMUCapsCPUFilterFeatures,
&qemuCaps->arch);
- } else if (virQEMUCapsTypeIsAccelerated(type) &&
- virCPUGetHostIsSupported(qemuCaps->arch)) {
+ }
+
+ cpuExpanded = virCPUDefCopy(cpu);
+ if (virCPUExpandFeatures(qemuCaps->arch, cpuExpanded) < 0)
+ goto error;
+
+ if (rc == 0 &&
+ virQEMUCapsTypeIsAccelerated(type) &&
+ virCPUGetHostIsSupported(qemuCaps->arch)) {
if (!(fullCPU = virQEMUCapsProbeHostCPU(qemuCaps->arch, NULL)))
goto error;
- cpuExpanded = virCPUDefCopy(cpu);
-
- if (virCPUExpandFeatures(qemuCaps->arch, cpuExpanded) < 0)
- goto error;
-
for (i = 0; i < cpuExpanded->nfeatures; i++) {
if (cpuExpanded->features[i].policy == VIR_CPU_FEATURE_REQUIRE)
virCPUDefUpdateFeature(fullCPU, cpuExpanded->features[i].name,
@@ -4171,6 +4185,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
virQEMUCapsSetHostModel(qemuCaps, type, physAddrSize,
g_steal_pointer(&cpu),
+ g_steal_pointer(&cpuExpanded),
g_steal_pointer(&migCPU),
g_steal_pointer(&fullCPU));
@@ -6587,9 +6602,14 @@ virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
virDomainCaps *domCaps,
unsigned int flags)
{
- virQEMUCapsHostCPUType cpuType = VIR_QEMU_CAPS_HOST_CPU_REPORTED;
+ virQEMUCapsHostCPUType cpuType;
virCPUDef *cpu;
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES)
+ cpuType = VIR_QEMU_CAPS_HOST_CPU_EXPANDED;
+ else
+ cpuType = VIR_QEMU_CAPS_HOST_CPU_REPORTED;
+
cpu = virCPUDefCopy(virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
cpuType));
@@ -6600,9 +6620,6 @@ virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
cpu, VIR_CPU_FEATURE_DISABLE);
}
- if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES)
- virCPUExpandFeatures(domCaps->arch, cpu);
-
virCPUDefSortFeatures(cpu);
domCaps->cpu.hostModel = cpu;
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index bc3ecbb89f..8822bf120b 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -788,6 +788,9 @@ typedef enum {
* combined with features reported by QEMU. This is used for backward
* compatible comparison between a guest CPU and a host CPU. */
VIR_QEMU_CAPS_HOST_CPU_FULL,
+ /* Expanded host CPU definition with features that are implicitly enabled
+ * by the selected CPU model. */
+ VIR_QEMU_CAPS_HOST_CPU_EXPANDED,
} virQEMUCapsHostCPUType;
virCPUDef *virQEMUCapsGetHostModel(virQEMUCaps *qemuCaps,
--
2.54.0

156
centos-9/SOURCES/libvirt-qemu_capabilities-Fix-domain-capabilities-on-AMD-CPUs.patch

@ -0,0 +1,156 @@
From ce373eb396f931d5ebdd03105a3f1950eb842cfd Mon Sep 17 00:00:00 2001
Message-ID: <ce373eb396f931d5ebdd03105a3f1950eb842cfd.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Mon, 25 May 2026 14:31:07 +0200
Subject: [PATCH] qemu_capabilities: Fix domain capabilities on AMD CPUs
The arch-capabilities MSR is not defined on AMD CPUs, but KVM has always
been emulating them. Unfortunately, this may cause Windows to crash so
QEMU (since 10.1, commit d3a24134e37d57abd3e7445842cda2717f49e96d)
decided to mask the MSR by default with some additional compatibility
code for older machine types.
This is all mostly transparent except for probing when we run QEMU
without a machine type and expand the "host" CPU model. With QEMU 10.1
and newer none of the arch-capabilities features will be shown as
enabled, which may cause unexpected issues for users (such as KubeVirt)
that get the list of all supported features from the host-model CPU
definition in domain capabilities to select possible target nodes for
migration. As a result of the change, no AMD host with new QEMU will be
shown as available for incoming migration from older hosts.
Since the features are supported on the host (it's possible to
explicitly enable them), but they should not be enabled by default in
host-model CPU, we only add the to domain capabilities when
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES flag is set.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 54ff2058d6f7bb2547afebbd9c65c7b4b501e372)
https://redhat.atlassian.net/browse/RHEL-177364
Conflicts:
tests/domaincapsdata/qemu_11.0.0-q35.x86_64+sgx-supported.xml
tests/domaincapsdata/qemu_11.0.0-q35.x86_64-supported.xml
- QEMU 11.0 data do not exist downstream
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 24 +++++++++++++++++++
src/qemu/qemu_driver.c | 3 ++-
.../qemu_10.1.0-q35.x86_64-supported.xml | 7 ++++++
.../qemu_10.2.0-q35.x86_64-supported.xml | 7 ++++++
4 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 555723cafb..f06f376dd7 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -6604,6 +6604,7 @@ virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
{
virQEMUCapsHostCPUType cpuType;
virCPUDef *cpu;
+ virArch arch = domCaps->arch;
if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES)
cpuType = VIR_QEMU_CAPS_HOST_CPU_EXPANDED;
@@ -6620,6 +6621,29 @@ virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
cpu, VIR_CPU_FEATURE_DISABLE);
}
+ if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES) {
+ uint32_t index = 0x10a; /* arch-capabilities MSR */
+ uint64_t msr = 0;
+
+ /* While the arch-capabilities MSR is not defined on AMD CPUs, KVM has
+ * always been emulating them. Unfortunately, this may cause some
+ * Windows version to crash so QEMU decided to mask the MSR by default.
+ * When asked for all CPU features supported on a host we need to add
+ * the affected features to the host-model.
+ */
+ if (ARCH_IS_X86(arch) &&
+ STREQ_NULLABLE(cpu->vendor, "AMD") &&
+ virCPUCheckFeature(arch, cpu, "arch-capabilities") == 0 &&
+ virHostCPUGetMSRFromKVM(index, &msr) == 0) {
+ g_autoptr(virCPUData) data = virCPUDataNew(arch);
+ virCPUFeaturePolicy policy = VIR_CPU_FEATURE_REQUIRE;
+
+ virCPUx86DataAddMSR(data, index, msr);
+ virCPUUpdateFeatures(arch, cpu, data, policy);
+ virCPUDefUpdateFeature(cpu, "arch-capabilities", policy);
+ }
+ }
+
virCPUDefSortFeatures(cpu);
domCaps->cpu.hostModel = cpu;
}
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0a61f97666..dcb49a9d42 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16721,7 +16721,8 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
g_autoptr(virDomainCaps) domCaps = NULL;
virCheckFlags(VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES |
- VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES,
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES |
+ VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES,
NULL);
if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0)
diff --git a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64-supported.xml b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64-supported.xml
index 244fce575b..4ea61a6cbe 100644
--- a/tests/domaincapsdata/qemu_10.1.0-q35.x86_64-supported.xml
+++ b/tests/domaincapsdata/qemu_10.1.0-q35.x86_64-supported.xml
@@ -45,17 +45,24 @@
<vendor>AMD</vendor>
<maxphysaddr mode='passthrough' limit='64'/>
<feature policy='require' name='amd-ssbd'/>
+ <feature policy='require' name='arch-capabilities'/>
<feature policy='require' name='cmp_legacy'/>
<feature policy='require' name='flushbyasid'/>
+ <feature policy='require' name='gds-no'/>
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='ibpb-brtype'/>
<feature policy='require' name='invtsc'/>
<feature policy='require' name='lbrv'/>
<feature policy='require' name='lfence-always-serializing'/>
+ <feature policy='require' name='mds-no'/>
<feature policy='require' name='null-sel-clr-base'/>
<feature policy='require' name='overflow-recov'/>
<feature policy='require' name='pause-filter'/>
<feature policy='require' name='pfthreshold'/>
+ <feature policy='require' name='pschange-mc-no'/>
+ <feature policy='require' name='rdctl-no'/>
+ <feature policy='require' name='rfds-no'/>
+ <feature policy='require' name='skip-l1dfl-vmentry'/>
<feature policy='require' name='ssbd'/>
<feature policy='require' name='stibp'/>
<feature policy='require' name='succor'/>
diff --git a/tests/domaincapsdata/qemu_10.2.0-q35.x86_64-supported.xml b/tests/domaincapsdata/qemu_10.2.0-q35.x86_64-supported.xml
index 9389141012..d9c0ea6f1d 100644
--- a/tests/domaincapsdata/qemu_10.2.0-q35.x86_64-supported.xml
+++ b/tests/domaincapsdata/qemu_10.2.0-q35.x86_64-supported.xml
@@ -44,12 +44,19 @@
<model fallback='forbid'>EPYC-Turin</model>
<vendor>AMD</vendor>
<maxphysaddr mode='passthrough' limit='64'/>
+ <feature policy='require' name='arch-capabilities'/>
<feature policy='require' name='cmp_legacy'/>
<feature policy='require' name='flush-l1d'/>
+ <feature policy='require' name='gds-no'/>
<feature policy='require' name='hypervisor'/>
<feature policy='require' name='invtsc'/>
<feature policy='disable' name='la57'/>
+ <feature policy='require' name='mds-no'/>
<feature policy='disable' name='pcid'/>
+ <feature policy='require' name='pschange-mc-no'/>
+ <feature policy='require' name='rdctl-no'/>
+ <feature policy='require' name='rfds-no'/>
+ <feature policy='require' name='skip-l1dfl-vmentry'/>
<feature policy='require' name='spec-ctrl'/>
<feature policy='require' name='ssbd'/>
<feature policy='require' name='stibp'/>
--
2.54.0

71
centos-9/SOURCES/libvirt-qemu_capabilities-Split-conditions-in-virQEMUCapsInitHostCPUModel.patch

@ -0,0 +1,71 @@
From 1b72f3955f62a442b8482eed46e6456ba2e1c14b Mon Sep 17 00:00:00 2001
Message-ID: <1b72f3955f62a442b8482eed46e6456ba2e1c14b.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Thu, 21 May 2026 17:30:21 +0200
Subject: [PATCH] qemu_capabilities: Split conditions in
virQEMUCapsInitHostCPUModel
Having 'else' after goto is useless.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 8b4f56447f32171671e18b82fbdfd478f2ec4293)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2265dae7ba..2e8f220abc 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4102,9 +4102,17 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
if (!(cpu = virQEMUCapsNewHostCPUModel()))
goto error;
- if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0) {
+ if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, cpu, false)) < 0)
goto error;
- } else if (rc == 1) {
+
+ if (rc == 2) {
+ VIR_DEBUG("QEMU does not provide CPU model for arch=%s virttype=%s",
+ virArchToString(qemuCaps->arch),
+ virDomainVirtTypeToString(type));
+ goto error;
+ }
+
+ if (rc == 1) {
g_autoptr(virDomainCapsCPUModels) cpuModels = NULL;
VIR_DEBUG("No host CPU model info from QEMU; probing host CPU directly");
@@ -4115,11 +4123,6 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
virCPUDefCopyModelFilter(cpu, hostCPU, true, virQEMUCapsCPUFilterFeatures,
&qemuCaps->arch);
- } else if (rc == 2) {
- VIR_DEBUG("QEMU does not provide CPU model for arch=%s virttype=%s",
- virArchToString(qemuCaps->arch),
- virDomainVirtTypeToString(type));
- goto error;
} else if (virQEMUCapsTypeIsAccelerated(type) &&
virCPUGetHostIsSupported(qemuCaps->arch)) {
if (!(fullCPU = virQEMUCapsProbeHostCPU(qemuCaps->arch, NULL)))
@@ -4140,9 +4143,10 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
if (!(migCPU = virQEMUCapsNewHostCPUModel()))
goto error;
- if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, migCPU, true)) < 0) {
+ if ((rc = virQEMUCapsInitCPUModel(qemuCaps, type, migCPU, true)) < 0)
goto error;
- } else if (rc == 1) {
+
+ if (rc == 1) {
VIR_DEBUG("CPU migratability not provided by QEMU");
virCPUDefFree(migCPU);
--
2.54.0

150
centos-9/SOURCES/libvirt-qemu_capabilities-Split-virQEMUCapsFillDomainCPUCaps.patch

@ -0,0 +1,150 @@
From b41da9180160e455bf36d9db7870b64457a6ca8c Mon Sep 17 00:00:00 2001
Message-ID: <b41da9180160e455bf36d9db7870b64457a6ca8c.1780571166.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Thu, 21 May 2026 12:24:25 +0200
Subject: [PATCH] qemu_capabilities: Split virQEMUCapsFillDomainCPUCaps
Each CPU mode is filled in its own dedicated function.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 354ac21caba1da52d3d48e57c7395f899efc9ca4)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 96 ++++++++++++++++++++++++------------
1 file changed, 64 insertions(+), 32 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index ed6aa86da2..0b32296cc8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -6553,6 +6553,66 @@ virQEMUCapsFillDomainOSCaps(virDomainCapsOS *os,
}
+static void
+virQEMUCapsFillDomainCPUHostPassthrough(virQEMUCaps *qemuCaps,
+ virDomainCaps *domCaps)
+{
+ domCaps->cpu.hostPassthrough = true;
+
+ domCaps->cpu.hostPassthroughMigratable.report = true;
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_MIGRATABLE)) {
+ VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.hostPassthroughMigratable,
+ VIR_TRISTATE_SWITCH_ON);
+ }
+ VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.hostPassthroughMigratable,
+ VIR_TRISTATE_SWITCH_OFF);
+}
+
+
+static void
+virQEMUCapsFillDomainCPUMaximum(virDomainCaps *domCaps)
+{
+ domCaps->cpu.maximum = true;
+
+ domCaps->cpu.maximumMigratable.report = true;
+ VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.maximumMigratable,
+ VIR_TRISTATE_SWITCH_ON);
+ VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.maximumMigratable,
+ VIR_TRISTATE_SWITCH_OFF);
+}
+
+
+static void
+virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps,
+ virDomainCaps *domCaps)
+{
+ virCPUDef *cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
+ VIR_QEMU_CAPS_HOST_CPU_REPORTED);
+
+ domCaps->cpu.hostModel = virCPUDefCopy(cpu);
+ domCaps->cpu.hostModel->addr = virQEMUCapsGetHostPhysAddr(qemuCaps,
+ domCaps->virttype);
+}
+
+
+static void
+virQEMUCapsFillDomainCPUCustom(virQEMUCaps *qemuCaps,
+ virDomainCaps *domCaps)
+{
+ const char *forbidden[] = { "host", NULL };
+ g_auto(GStrv) models = NULL;
+
+ if (virCPUGetModels(domCaps->arch, &models) >= 0) {
+ domCaps->cpu.custom = virQEMUCapsGetCPUModels(qemuCaps,
+ domCaps->virttype,
+ (const char **)models,
+ forbidden);
+ } else {
+ domCaps->cpu.custom = NULL;
+ }
+}
+
+
static void
virQEMUCapsFillDomainCPUCaps(virQEMUCaps *qemuCaps,
virArch hostarch,
@@ -6561,53 +6621,25 @@ virQEMUCapsFillDomainCPUCaps(virQEMUCaps *qemuCaps,
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
VIR_CPU_MODE_HOST_PASSTHROUGH,
domCaps->machine)) {
- domCaps->cpu.hostPassthrough = true;
-
- domCaps->cpu.hostPassthroughMigratable.report = true;
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_CPU_MIGRATABLE)) {
- VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.hostPassthroughMigratable,
- VIR_TRISTATE_SWITCH_ON);
- }
- VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.hostPassthroughMigratable,
- VIR_TRISTATE_SWITCH_OFF);
+ virQEMUCapsFillDomainCPUHostPassthrough(qemuCaps, domCaps);
}
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
VIR_CPU_MODE_MAXIMUM,
domCaps->machine)) {
- domCaps->cpu.maximum = true;
-
- domCaps->cpu.maximumMigratable.report = true;
- VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.maximumMigratable,
- VIR_TRISTATE_SWITCH_ON);
- VIR_DOMAIN_CAPS_ENUM_SET(domCaps->cpu.maximumMigratable,
- VIR_TRISTATE_SWITCH_OFF);
+ virQEMUCapsFillDomainCPUMaximum(domCaps);
}
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
VIR_CPU_MODE_HOST_MODEL,
domCaps->machine)) {
- virCPUDef *cpu = virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype,
- VIR_QEMU_CAPS_HOST_CPU_REPORTED);
- domCaps->cpu.hostModel = virCPUDefCopy(cpu);
- domCaps->cpu.hostModel->addr = virQEMUCapsGetHostPhysAddr(qemuCaps,
- domCaps->virttype);
+ virQEMUCapsFillDomainCPUHostModel(qemuCaps, domCaps);
}
if (virQEMUCapsIsCPUModeSupported(qemuCaps, hostarch, domCaps->virttype,
VIR_CPU_MODE_CUSTOM,
domCaps->machine)) {
- const char *forbidden[] = { "host", NULL };
- g_auto(GStrv) models = NULL;
-
- if (virCPUGetModels(domCaps->arch, &models) >= 0) {
- domCaps->cpu.custom = virQEMUCapsGetCPUModels(qemuCaps,
- domCaps->virttype,
- (const char **)models,
- forbidden);
- } else {
- domCaps->cpu.custom = NULL;
- }
+ virQEMUCapsFillDomainCPUCustom(qemuCaps, domCaps);
}
}
--
2.54.0

65
centos-9/SOURCES/libvirt-qemu_capabilities-Use-g_autoptr-in-virQEMUCapsInitHostCPUModel.patch

@ -0,0 +1,65 @@
From 2141acf3d9891c1451d741abc1d043e35b1ed074 Mon Sep 17 00:00:00 2001
Message-ID: <2141acf3d9891c1451d741abc1d043e35b1ed074.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Thu, 21 May 2026 14:15:01 +0200
Subject: [PATCH] qemu_capabilities: Use g_autoptr in
virQEMUCapsInitHostCPUModel
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit eca4c6672d3f373bb9cff271adfc2cd8b13cb4bc)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/qemu/qemu_capabilities.c | 22 +++++++++-------------
1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 6951e50c03..2265dae7ba 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -4087,11 +4087,11 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
virArch hostArch,
virDomainVirtType type)
{
- virCPUDef *cpu = NULL;
- virCPUDef *cpuExpanded = NULL;
- virCPUDef *migCPU = NULL;
- virCPUDef *hostCPU = NULL;
- virCPUDef *fullCPU = NULL;
+ g_autoptr(virCPUDef) cpu = NULL;
+ g_autoptr(virCPUDef) cpuExpanded = NULL;
+ g_autoptr(virCPUDef) migCPU = NULL;
+ g_autoptr(virCPUDef) hostCPU = NULL;
+ g_autoptr(virCPUDef) fullCPU = NULL;
unsigned int physAddrSize = 0;
size_t i;
int rc;
@@ -4165,19 +4165,15 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps,
if (virQEMUCapsTypeIsAccelerated(type))
virHostCPUGetPhysAddrSize(hostArch, &physAddrSize);
- virQEMUCapsSetHostModel(qemuCaps, type, physAddrSize, cpu, migCPU, fullCPU);
+ virQEMUCapsSetHostModel(qemuCaps, type, physAddrSize,
+ g_steal_pointer(&cpu),
+ g_steal_pointer(&migCPU),
+ g_steal_pointer(&fullCPU));
- cleanup:
- virCPUDefFree(cpuExpanded);
- virCPUDefFree(hostCPU);
return;
error:
- virCPUDefFree(cpu);
- virCPUDefFree(migCPU);
- virCPUDefFree(fullCPU);
virResetLastError();
- goto cleanup;
}
--
2.54.0

611
centos-9/SOURCES/libvirt-security-Cleanup-hostdev-label-error-logic.patch

@ -0,0 +1,611 @@
From ab58ab56b88b4a5fc4a2d5dc85b249220951ce36 Mon Sep 17 00:00:00 2001
Message-ID: <ab58ab56b88b4a5fc4a2d5dc85b249220951ce36.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 2 Mar 2026 12:46:00 +0100
Subject: [PATCH] security: Cleanup hostdev label error logic
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Current code used mix of return, goto, break and setting ret variable.
Simplify the logic to just return -1 on error.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit b7483e6558acbb0d80e2ff2c3648ca63cb7f41f9)
Resolves: https://redhat.atlassian.net/browse/RHEL-159902
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/security/security_apparmor.c | 56 +++++++++--------
src/security/security_dac.c | 103 ++++++++++++++++++-------------
src/security/security_selinux.c | 87 ++++++++++++++------------
3 files changed, 139 insertions(+), 107 deletions(-)
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 74c5b10063..1c3496893c 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -800,7 +800,6 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
const char *vroot)
{
g_autofree struct SDPDOP *ptr = NULL;
- int ret = -1;
virSecurityLabelDef *secdef =
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
virDomainHostdevSubsysUSB *usbsrc = &dev->source.subsys.u.usb;
@@ -834,9 +833,10 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
g_autoptr(virUSBDevice) usb =
virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot);
if (!usb)
- goto done;
+ return -1;
- ret = virUSBDeviceFileIterate(usb, AppArmorSetSecurityUSBLabel, ptr);
+ if (virUSBDeviceFileIterate(usb, AppArmorSetSecurityUSBLabel, ptr) < 0)
+ return -1;
break;
}
@@ -845,30 +845,32 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
virPCIDeviceNew(&pcisrc->addr);
if (!pci)
- goto done;
+ return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
- if (!vfioGroupDev) {
- goto done;
- }
- ret = AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr);
+ if (!vfioGroupDev)
+ return -1;
+
+ if (AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr) < 0)
+ return -1;
} else {
g_autofree char *vfiofdDev = NULL;
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
- goto done;
+ return -1;
- ret = AppArmorSetSecurityPCILabel(pci, vfiofdDev, ptr);
- if (ret < 0)
- goto done;
+ if (AppArmorSetSecurityPCILabel(pci, vfiofdDev, ptr) < 0)
+ return -1;
- ret = AppArmorSetSecurityPCILabel(pci, VIR_IOMMU_DEV_PATH, ptr);
+ if (AppArmorSetSecurityPCILabel(pci, VIR_IOMMU_DEV_PATH, ptr) < 0)
+ return -1;
}
} else {
- ret = virPCIDeviceFileIterate(pci, AppArmorSetSecurityPCILabel, ptr);
+ if (virPCIDeviceFileIterate(pci, AppArmorSetSecurityPCILabel, ptr) < 0)
+ return -1;
}
break;
}
@@ -881,10 +883,11 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
scsihostsrc->target, scsihostsrc->unit,
dev->readonly, dev->shareable);
- if (!scsi)
- goto done;
+ if (!scsi)
+ return -1;
- ret = virSCSIDeviceFileIterate(scsi, AppArmorSetSecuritySCSILabel, ptr);
+ if (virSCSIDeviceFileIterate(scsi, AppArmorSetSecuritySCSILabel, ptr) < 0)
+ return -1;
break;
}
@@ -892,11 +895,13 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
g_autoptr(virSCSIVHostDevice) host = virSCSIVHostDeviceNew(hostsrc->wwpn);
if (!host)
- goto done;
+ return -1;
- ret = virSCSIVHostDeviceFileIterate(host,
- AppArmorSetSecurityHostLabel,
- ptr);
+ if (virSCSIVHostDeviceFileIterate(host,
+ AppArmorSetSecurityHostLabel,
+ ptr) < 0) {
+ return -1;
+ }
break;
}
@@ -904,19 +909,18 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
g_autofree char *vfiodev = NULL;
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
- goto done;
+ return -1;
- ret = AppArmorSetSecurityHostdevLabelHelper(vfiodev, ptr);
+ if (AppArmorSetSecurityHostdevLabelHelper(vfiodev, ptr) < 0)
+ return -1;
break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
- ret = 0;
break;
}
- done:
- return ret;
+ return 0;
}
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 704c8dbfec..2a4c7f6a3c 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1234,7 +1234,6 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
virDomainHostdevSubsysSCSI *scsisrc = &dev->source.subsys.u.scsi;
virDomainHostdevSubsysSCSIVHost *hostsrc = &dev->source.subsys.u.scsi_host;
virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev;
- int ret = -1;
if (!priv->dynamicOwnership)
return 0;
@@ -1265,9 +1264,11 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
if (!(usb = virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot)))
return -1;
- ret = virUSBDeviceFileIterate(usb,
- virSecurityDACSetUSBLabel,
- &cbdata);
+ if (virUSBDeviceFileIterate(usb,
+ virSecurityDACSetUSBLabel,
+ &cbdata) < 0) {
+ return -1;
+ }
break;
}
@@ -1275,7 +1276,7 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
g_autoptr(virPCIDevice) pci = NULL;
if (!virPCIDeviceExists(&pcisrc->addr))
- break;
+ return -1;
pci = virPCIDeviceNew(&pcisrc->addr);
@@ -1289,25 +1290,29 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
if (!vfioGroupDev)
return -1;
- ret = virSecurityDACSetHostdevLabelHelper(vfioGroupDev,
- false,
- &cbdata);
+ if (virSecurityDACSetHostdevLabelHelper(vfioGroupDev,
+ false,
+ &cbdata) < 0) {
+ return -1;
+ }
} else {
g_autofree char *vfiofdDev = NULL;
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
return -1;
- ret = virSecurityDACSetHostdevLabelHelper(vfiofdDev, false, &cbdata);
- if (ret < 0)
- break;
+ if (virSecurityDACSetHostdevLabelHelper(vfiofdDev, false, &cbdata) < 0)
+ return -1;
- ret = virSecurityDACSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &cbdata);
+ if (virSecurityDACSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &cbdata) < 0)
+ return -1;
}
} else {
- ret = virPCIDeviceFileIterate(pci,
- virSecurityDACSetPCILabel,
- &cbdata);
+ if (virPCIDeviceFileIterate(pci,
+ virSecurityDACSetPCILabel,
+ &cbdata) < 0) {
+ return -1;
+ }
}
break;
}
@@ -1323,9 +1328,11 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
if (!scsi)
return -1;
- ret = virSCSIDeviceFileIterate(scsi,
- virSecurityDACSetSCSILabel,
- &cbdata);
+ if (virSCSIDeviceFileIterate(scsi,
+ virSecurityDACSetSCSILabel,
+ &cbdata) < 0) {
+ return -1;
+ }
break;
}
@@ -1335,9 +1342,11 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
if (!host)
return -1;
- ret = virSCSIVHostDeviceFileIterate(host,
- virSecurityDACSetHostLabel,
- &cbdata);
+ if (virSCSIVHostDeviceFileIterate(host,
+ virSecurityDACSetHostLabel,
+ &cbdata) < 0) {
+ return -1;
+ }
break;
}
@@ -1347,16 +1356,16 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
return -1;
- ret = virSecurityDACSetHostdevLabelHelper(vfiodev, false, &cbdata);
+ if (virSecurityDACSetHostdevLabelHelper(vfiodev, false, &cbdata) < 0)
+ return -1;
break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
- ret = 0;
break;
}
- return ret;
+ return 0;
}
@@ -1414,7 +1423,6 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
virDomainHostdevSubsysSCSI *scsisrc = &dev->source.subsys.u.scsi;
virDomainHostdevSubsysSCSIVHost *hostsrc = &dev->source.subsys.u.scsi_host;
virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev;
- int ret = -1;
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
@@ -1441,7 +1449,8 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
if (!(usb = virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot)))
return -1;
- ret = virUSBDeviceFileIterate(usb, virSecurityDACRestoreUSBLabel, mgr);
+ if (virUSBDeviceFileIterate(usb, virSecurityDACRestoreUSBLabel, mgr) < 0)
+ return -1;
break;
}
@@ -1449,7 +1458,7 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
g_autoptr(virPCIDevice) pci = NULL;
if (!virPCIDeviceExists(&pcisrc->addr))
- break;
+ return -1;
pci = virPCIDeviceNew(&pcisrc->addr);
@@ -1463,24 +1472,29 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
if (!vfioGroupDev)
return -1;
- ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL,
- vfioGroupDev, false);
+ if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
+ vfioGroupDev, false) < 0) {
+ return -1;
+ }
} else {
g_autofree char *vfiofdDev = NULL;
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
return -1;
- ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL,
- vfiofdDev, false);
- if (ret < 0)
- break;
+ if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
+ vfiofdDev, false) < 0) {
+ return -1;
+ }
- ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL,
- VIR_IOMMU_DEV_PATH, false);
+ if (virSecurityDACRestoreFileLabelInternal(mgr, NULL,
+ VIR_IOMMU_DEV_PATH, false) < 0) {
+ return -1;
+ }
}
} else {
- ret = virPCIDeviceFileIterate(pci, virSecurityDACRestorePCILabel, mgr);
+ if (virPCIDeviceFileIterate(pci, virSecurityDACRestorePCILabel, mgr) < 0)
+ return -1;
}
break;
}
@@ -1496,7 +1510,8 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
if (!scsi)
return -1;
- ret = virSCSIDeviceFileIterate(scsi, virSecurityDACRestoreSCSILabel, mgr);
+ if (virSCSIDeviceFileIterate(scsi, virSecurityDACRestoreSCSILabel, mgr) < 0)
+ return -1;
break;
}
@@ -1506,9 +1521,11 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
if (!host)
return -1;
- ret = virSCSIVHostDeviceFileIterate(host,
- virSecurityDACRestoreHostLabel,
- mgr);
+ if (virSCSIVHostDeviceFileIterate(host,
+ virSecurityDACRestoreHostLabel,
+ mgr) < 0) {
+ return -1;
+ }
break;
}
@@ -1518,16 +1535,16 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
return -1;
- ret = virSecurityDACRestoreFileLabelInternal(mgr, NULL, vfiodev, false);
+ if (virSecurityDACRestoreFileLabelInternal(mgr, NULL, vfiodev, false) < 0)
+ return -1;
break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
- ret = 0;
break;
}
- return ret;
+ return 0;
}
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 4a5f61d16b..96ca59a7a4 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -2219,8 +2219,6 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev;
virSecuritySELinuxCallbackData data = {.mgr = mgr, .def = def};
- int ret = -1;
-
/* Like virSecuritySELinuxSetImageLabelInternal() for a networked
* disk, do nothing for an iSCSI hostdev
*/
@@ -2241,7 +2239,8 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
if (!usb)
return -1;
- ret = virUSBDeviceFileIterate(usb, virSecuritySELinuxSetUSBLabel, &data);
+ if (virUSBDeviceFileIterate(usb, virSecuritySELinuxSetUSBLabel, &data) < 0)
+ return -1;
break;
}
@@ -2249,7 +2248,7 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
g_autoptr(virPCIDevice) pci = NULL;
if (!virPCIDeviceExists(&pcisrc->addr))
- break;
+ return -1;
pci = virPCIDeviceNew(&pcisrc->addr);
@@ -2263,23 +2262,26 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
if (!vfioGroupDev)
return -1;
- ret = virSecuritySELinuxSetHostdevLabelHelper(vfioGroupDev,
- false,
- &data);
+ if (virSecuritySELinuxSetHostdevLabelHelper(vfioGroupDev,
+ false,
+ &data) < 0) {
+ return -1;
+ }
} else {
g_autofree char *vfiofdDev = NULL;
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
return -1;
- ret = virSecuritySELinuxSetHostdevLabelHelper(vfiofdDev, false, &data);
- if (ret)
- break;
+ if (virSecuritySELinuxSetHostdevLabelHelper(vfiofdDev, false, &data) < 0)
+ return -1;
- ret = virSecuritySELinuxSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &data);
+ if (virSecuritySELinuxSetHostdevLabelHelper(VIR_IOMMU_DEV_PATH, false, &data) < 0)
+ return -1;
}
} else {
- ret = virPCIDeviceFileIterate(pci, virSecuritySELinuxSetPCILabel, &data);
+ if (virPCIDeviceFileIterate(pci, virSecuritySELinuxSetPCILabel, &data) < 0)
+ return -1;
}
break;
}
@@ -2296,9 +2298,11 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
if (!scsi)
return -1;
- ret = virSCSIDeviceFileIterate(scsi,
- virSecuritySELinuxSetSCSILabel,
- &data);
+ if (virSCSIDeviceFileIterate(scsi,
+ virSecuritySELinuxSetSCSILabel,
+ &data) < 0) {
+ return -1;
+ }
break;
}
@@ -2308,9 +2312,11 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
if (!host)
return -1;
- ret = virSCSIVHostDeviceFileIterate(host,
- virSecuritySELinuxSetHostLabel,
- &data);
+ if (virSCSIVHostDeviceFileIterate(host,
+ virSecuritySELinuxSetHostLabel,
+ &data) < 0) {
+ return -1;
+ }
break;
}
@@ -2318,18 +2324,18 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
g_autofree char *vfiodev = NULL;
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
- return ret;
+ return -1;
- ret = virSecuritySELinuxSetHostdevLabelHelper(vfiodev, false, &data);
+ if (virSecuritySELinuxSetHostdevLabelHelper(vfiodev, false, &data) < 0)
+ return -1;
break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
- ret = 0;
break;
}
- return ret;
+ return 0;
}
@@ -2467,7 +2473,6 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
virDomainHostdevSubsysSCSI *scsisrc = &dev->source.subsys.u.scsi;
virDomainHostdevSubsysSCSIVHost *hostsrc = &dev->source.subsys.u.scsi_host;
virDomainHostdevSubsysMediatedDev *mdevsrc = &dev->source.subsys.u.mdev;
- int ret = -1;
/* Like virSecuritySELinuxRestoreImageLabelInt() for a networked
* disk, do nothing for an iSCSI hostdev
@@ -2489,7 +2494,8 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
if (!usb)
return -1;
- ret = virUSBDeviceFileIterate(usb, virSecuritySELinuxRestoreUSBLabel, mgr);
+ if (virUSBDeviceFileIterate(usb, virSecuritySELinuxRestoreUSBLabel, mgr) < 0)
+ return -1;
break;
}
@@ -2497,7 +2503,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
g_autoptr(virPCIDevice) pci = NULL;
if (!virPCIDeviceExists(&pcisrc->addr))
- break;
+ return -1;
pci = virPCIDeviceNew(&pcisrc->addr);
@@ -2511,21 +2517,23 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
if (!vfioGroupDev)
return -1;
- ret = virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false, false);
+ if (virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, false, false) < 0)
+ return -1;
} else {
g_autofree char *vfiofdDev = NULL;
if (virPCIDeviceGetVfioPath(pci, &vfiofdDev) < 0)
return -1;
- ret = virSecuritySELinuxRestoreFileLabel(mgr, vfiofdDev, false, false);
- if (ret < 0)
- break;
+ if (virSecuritySELinuxRestoreFileLabel(mgr, vfiofdDev, false, false) < 0)
+ return -1;
- ret = virSecuritySELinuxRestoreFileLabel(mgr, VIR_IOMMU_DEV_PATH, false, false);
+ if (virSecuritySELinuxRestoreFileLabel(mgr, VIR_IOMMU_DEV_PATH, false, false) < 0)
+ return -1;
}
} else {
- ret = virPCIDeviceFileIterate(pci, virSecuritySELinuxRestorePCILabel, mgr);
+ if (virPCIDeviceFileIterate(pci, virSecuritySELinuxRestorePCILabel, mgr) < 0)
+ return -1;
}
break;
}
@@ -2541,7 +2549,8 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
if (!scsi)
return -1;
- ret = virSCSIDeviceFileIterate(scsi, virSecuritySELinuxRestoreSCSILabel, mgr);
+ if (virSCSIDeviceFileIterate(scsi, virSecuritySELinuxRestoreSCSILabel, mgr) < 0)
+ return -1;
break;
}
@@ -2551,9 +2560,11 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
if (!host)
return -1;
- ret = virSCSIVHostDeviceFileIterate(host,
- virSecuritySELinuxRestoreHostLabel,
- mgr);
+ if (virSCSIVHostDeviceFileIterate(host,
+ virSecuritySELinuxRestoreHostLabel,
+ mgr) < 0) {
+ return -1;
+ }
break;
}
@@ -2563,16 +2574,16 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
return -1;
- ret = virSecuritySELinuxRestoreFileLabel(mgr, vfiodev, false, false);
+ if (virSecuritySELinuxRestoreFileLabel(mgr, vfiodev, false, false) < 0)
+ return -1;
break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
- ret = 0;
break;
}
- return ret;
+ return 0;
}
--
2.54.0

118
centos-9/SOURCES/libvirt-security_apparmor-Use-g_auto-in-AppArmorSetSecurityHostdevLabel.patch

@ -0,0 +1,118 @@
From b2037dd33febe910a6dad3521549b747322d37cb Mon Sep 17 00:00:00 2001
Message-ID: <b2037dd33febe910a6dad3521549b747322d37cb.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 2 Mar 2026 12:47:43 +0100
Subject: [PATCH] security_apparmor: Use g_auto* in
AppArmorSetSecurityHostdevLabel
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 75f698c77f0705ae9793331eadb08fbbf89572f6)
Resolves: https://redhat.atlassian.net/browse/RHEL-159902
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/security/security_apparmor.c | 20 ++++++--------------
1 file changed, 6 insertions(+), 14 deletions(-)
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 6c5da2a650..74c5b10063 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -799,7 +799,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
virDomainHostdevDef *dev,
const char *vroot)
{
- struct SDPDOP *ptr;
+ g_autofree struct SDPDOP *ptr = NULL;
int ret = -1;
virSecurityLabelDef *secdef =
virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
@@ -831,13 +831,12 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
switch (dev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
- virUSBDevice *usb =
+ g_autoptr(virUSBDevice) usb =
virUSBDeviceNew(usbsrc->bus, usbsrc->device, vroot);
if (!usb)
goto done;
ret = virUSBDeviceFileIterate(usb, AppArmorSetSecurityUSBLabel, ptr);
- virUSBDeviceFree(usb);
break;
}
@@ -850,13 +849,12 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
- char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
+ g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
if (!vfioGroupDev) {
goto done;
}
ret = AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr);
- VIR_FREE(vfioGroupDev);
} else {
g_autofree char *vfiofdDev = NULL;
@@ -877,7 +875,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: {
virDomainHostdevSubsysSCSIHost *scsihostsrc = &scsisrc->u.host;
- virSCSIDevice *scsi =
+ g_autoptr(virSCSIDevice) scsi =
virSCSIDeviceNew(NULL,
scsihostsrc->adapter, scsihostsrc->bus,
scsihostsrc->target, scsihostsrc->unit,
@@ -887,13 +885,11 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
goto done;
ret = virSCSIDeviceFileIterate(scsi, AppArmorSetSecuritySCSILabel, ptr);
- virSCSIDeviceFree(scsi);
-
break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: {
- virSCSIVHostDevice *host = virSCSIVHostDeviceNew(hostsrc->wwpn);
+ g_autoptr(virSCSIVHostDevice) host = virSCSIVHostDeviceNew(hostsrc->wwpn);
if (!host)
goto done;
@@ -901,19 +897,16 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
ret = virSCSIVHostDeviceFileIterate(host,
AppArmorSetSecurityHostLabel,
ptr);
- virSCSIVHostDeviceFree(host);
break;
}
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV: {
- char *vfiodev = NULL;
+ g_autofree char *vfiodev = NULL;
if (!(vfiodev = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
goto done;
ret = AppArmorSetSecurityHostdevLabelHelper(vfiodev, ptr);
-
- VIR_FREE(vfiodev);
break;
}
@@ -923,7 +916,6 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
}
done:
- VIR_FREE(ptr);
return ret;
}
--
2.54.0

152
centos-9/SOURCES/libvirt-src-Use-virHostdevIsPCIDeviceWith-to-check-for-IOMMUFD.patch

@ -0,0 +1,152 @@
From 8442235a61de81d3572cc955a0b40969347fa6a1 Mon Sep 17 00:00:00 2001
Message-ID: <8442235a61de81d3572cc955a0b40969347fa6a1.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 12:25:13 +0100
Subject: [PATCH] src: Use virHostdevIsPCIDeviceWith* to check for IOMMUFD
Use virHostdevIsPCIDeviceWithIOMMUFD where we need to check if hostdev
is PCI device using IOMMUFD and virHostdevIsPCIDeviceWithoutIOMMUFD
where we need to check if hostdev is PCI device not using IOMMUFD.
Fixes: 7d2f91f9cb572ab95d0916bdd1a46dd198874529
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit c1d38e9428783730f063b59ad32f08d2e80aff9f)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_cgroup.c | 2 +-
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_namespace.c | 2 +-
src/qemu/qemu_validate.c | 2 +-
src/security/security_apparmor.c | 2 +-
src/security/security_dac.c | 4 ++--
src/security/security_selinux.c | 4 ++--
src/security/virt-aa-helper.c | 2 +-
8 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 6148990f19..0e1815f571 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -479,7 +479,7 @@ qemuSetupHostdevCgroup(virDomainObj *vm,
g_autofree char *path = NULL;
int perms;
- if (dev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES)
+ if (virHostdevIsPCIDeviceWithIOMMUFD(dev))
return 0;
if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index db512f6757..23e799de3c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5259,7 +5259,7 @@ qemuBuildHostdevCommandLine(virCommand *cmd,
if (qemuCommandAddExtDevice(cmd, hostdev->info, def, qemuCaps) < 0)
return -1;
- if (subsys->u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
qemuDomainHostdevPrivate *hostdevPriv = QEMU_DOMAIN_HOSTDEV_PRIVATE(hostdev);
qemuFDPassDirectTransferCommand(hostdevPriv->vfioDeviceFd, cmd);
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
index fb0734193d..4a063064f1 100644
--- a/src/qemu/qemu_namespace.c
+++ b/src/qemu/qemu_namespace.c
@@ -345,7 +345,7 @@ qemuDomainSetupHostdev(virDomainObj *vm,
{
g_autofree char *path = NULL;
- if (hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES)
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev))
return 0;
if (qemuDomainGetHostdevPath(hostdev, &path, NULL) < 0)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index 5c8c21335d..63c5f8e037 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -2722,7 +2722,7 @@ qemuValidateDomainDeviceDefHostdev(const virDomainHostdevDef *hostdev,
return -1;
}
- if (hostdev->source.subsys.u.pci.driver.iommufd == VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithIOMMUFD(hostdev)) {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_IOMMUFD)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("IOMMUFD is not supported by this version of qemu"));
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 40f13ec1a5..e53486ee0c 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -847,7 +847,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mgr,
return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
if (!vfioGroupDev)
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index d8cf117fc4..b891f6f121 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1283,7 +1283,7 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mgr,
return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
if (!vfioGroupDev)
@@ -1454,7 +1454,7 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager *mgr,
return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
if (!vfioGroupDev)
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 0fa50630f7..2b801aecd5 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -2255,7 +2255,7 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityManager *mgr,
return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
if (!vfioGroupDev)
@@ -2499,7 +2499,7 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecurityManager *mgr,
return -1;
if (pcisrc->driver.name == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO) {
- if (dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ if (virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
g_autofree char *vfioGroupDev = virPCIDeviceGetIOMMUGroupDev(pci);
if (!vfioGroupDev)
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 29e844c7ff..af95a64c42 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -1117,7 +1117,7 @@ get_files(vahControl * ctl)
if ((driverName == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO ||
driverName == VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_DEFAULT) &&
- dev->source.subsys.u.pci.driver.iommufd != VIR_TRISTATE_BOOL_YES) {
+ virHostdevIsPCIDeviceWithoutIOMMUFD(dev)) {
needsVfio = true;
}
--
2.54.0

266
centos-9/SOURCES/libvirt-tests-Add-iommufd-fdgroup-test.patch

@ -0,0 +1,266 @@
From c0d508913546c66014f4cad54779ff4ad1549d7a Mon Sep 17 00:00:00 2001
Message-ID: <c0d508913546c66014f4cad54779ff4ad1549d7a.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Mon, 16 Mar 2026 15:30:18 +0100
Subject: [PATCH] tests: Add iommufd fdgroup test
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 406b7fb0bd82251d94ce1fcb5fd7e35d51e1a1b7)
Conflicts:
- tests/qemuxmlconftest.c
missing upstream commit 6d6da1cbac4f0194ca257c8ff8f5038a96791a62
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_process.c | 14 +++--
src/qemu/qemu_processpriv.h | 2 +
.../iommufd-q35-fd.x86_64-latest.args | 41 +++++++++++++
.../iommufd-q35-fd.x86_64-latest.xml | 60 +++++++++++++++++++
tests/qemuxmlconfdata/iommufd-q35-fd.xml | 38 ++++++++++++
tests/qemuxmlconftest.c | 9 ++-
6 files changed, 159 insertions(+), 5 deletions(-)
create mode 100644 tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.args
create mode 100644 tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.xml
create mode 100644 tests/qemuxmlconfdata/iommufd-q35-fd.xml
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e4746374f6..b56e79ed1c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7712,9 +7712,11 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
*
* Find passed FD via virDomainFDAssociate() API for the VM.
*
+ * Exported only to be used in tests.
+ *
* Returns: 0 on success, -1 on failure
*/
-static int
+int
qemuProcessGetPassedIommuFd(virDomainObj *vm)
{
qemuDomainObjPrivate *priv = vm->privateData;
@@ -7734,10 +7736,14 @@ qemuProcessGetPassedIommuFd(virDomainObj *vm)
return -1;
}
- iommufd = dup(fdt->fds[0]);
+ if (fdt->testfds) {
+ iommufd = dup2(fdt->fds[0], fdt->testfds[0]);
+ } else {
+ iommufd = dup(fdt->fds[0]);
- if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0)
- return -1;
+ if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0)
+ return -1;
+ }
priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd);
diff --git a/src/qemu/qemu_processpriv.h b/src/qemu/qemu_processpriv.h
index 0ba5897f40..4bef5025b9 100644
--- a/src/qemu/qemu_processpriv.h
+++ b/src/qemu/qemu_processpriv.h
@@ -37,3 +37,5 @@ void qemuProcessHandleDeviceDeleted(qemuMonitor *mon,
const char *devAlias);
int qemuProcessQMPInitMonitor(qemuMonitor *mon);
+
+int qemuProcessGetPassedIommuFd(virDomainObj *vm);
diff --git a/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.args b/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.args
new file mode 100644
index 0000000000..7df3d173f3
--- /dev/null
+++ b/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.args
@@ -0,0 +1,41 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-q35-test \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-q35-test/.config \
+/usr/bin/qemu-system-x86_64 \
+-name guest=q35-test,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-q35-test/master-key.aes"}' \
+-machine q35,usb=off,dump-guest-core=off,memory-backend=pc.ram,acpi=off \
+-accel tcg \
+-cpu qemu64 \
+-m size=2097152k \
+-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":2147483648}' \
+-overcommit mem-lock=off \
+-smp 2,sockets=2,cores=1,threads=1 \
+-uuid 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device '{"driver":"pcie-root-port","port":16,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x2"}' \
+-device '{"driver":"pcie-root-port","port":17,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x2.0x1"}' \
+-device '{"driver":"qemu-xhci","id":"usb","bus":"pci.1","addr":"0x0"}' \
+-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-1-storage","read-only":false}' \
+-device '{"driver":"ide-hd","bus":"ide.0","drive":"libvirt-1-storage","id":"sata0-0-0","bootindex":1}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-device '{"driver":"qxl-vga","id":"video0","max_outputs":1,"ram_size":67108864,"vram_size":33554432,"vram64_size_mb":0,"vgamem_mb":8,"bus":"pcie.0","addr":"0x1"}' \
+-global ICH9-LPC.noreboot=off \
+-watchdog-action reset \
+-object '{"qom-type":"iommufd","id":"iommufd0","fd":"20"}' \
+-device '{"driver":"vfio-pci","id":"hostdev0","iommufd":"iommufd0","fd":"0","bus":"pcie.0","addr":"0x3"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.xml b/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.xml
new file mode 100644
index 0000000000..a6be49cbb3
--- /dev/null
+++ b/tests/qemuxmlconfdata/iommufd-q35-fd.x86_64-latest.xml
@@ -0,0 +1,60 @@
+<domain type='qemu'>
+ <name>q35-test</name>
+ <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid>
+ <memory unit='KiB'>2097152</memory>
+ <currentMemory unit='KiB'>2097152</currentMemory>
+ <vcpu placement='static' cpuset='0-1'>2</vcpu>
+ <iommufd enabled='yes' fdgroup='iommu'/>
+ <os>
+ <type arch='x86_64' machine='q35'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu mode='custom' match='exact' check='none'>
+ <model fallback='forbid'>qemu64</model>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <disk type='block' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='sda' bus='sata'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='1' port='0x10'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
+ </controller>
+ <controller type='pci' index='2' model='pcie-root-port'>
+ <model name='pcie-root-port'/>
+ <target chassis='2' port='0x11'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
+ </controller>
+ <controller type='sata' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
+ </controller>
+ <controller type='usb' index='0' model='qemu-xhci'>
+ <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
+ </controller>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <audio id='1' type='none'/>
+ <video>
+ <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1' primary='yes'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
+ </video>
+ <hostdev mode='subsystem' type='pci' managed='yes'>
+ <source>
+ <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/>
+ </source>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </hostdev>
+ <watchdog model='itco' action='reset'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/iommufd-q35-fd.xml b/tests/qemuxmlconfdata/iommufd-q35-fd.xml
new file mode 100644
index 0000000000..1cef31fffa
--- /dev/null
+++ b/tests/qemuxmlconfdata/iommufd-q35-fd.xml
@@ -0,0 +1,38 @@
+<domain type='qemu'>
+ <name>q35-test</name>
+ <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid>
+ <memory unit='KiB'>2097152</memory>
+ <currentMemory unit='KiB'>2097152</currentMemory>
+ <vcpu placement='static' cpuset='0-1'>2</vcpu>
+ <iommufd enabled='yes' fdgroup='iommu'/>
+ <os>
+ <type arch='x86_64' machine='q35'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='sda' bus='sata'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <hostdev mode='subsystem' type='pci' managed='yes'>
+ <source>
+ <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/>
+ </source>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+ </hostdev>
+ <controller type='sata' index='0'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <video>
+ <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
+ </video>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index aa877bf16a..29b7e1883c 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -30,6 +30,9 @@
# define LIBVIRT_QEMU_CAPSPRIV_H_ALLOW
# include "qemu/qemu_capspriv.h"
+# define LIBVIRT_QEMU_PROCESSPRIV_H_ALLOW
+# include "qemu/qemu_processpriv.h"
+
# include "testutilsqemu.h"
# define VIR_FROM_THIS VIR_FROM_QEMU
@@ -408,7 +411,9 @@ testQemuPrepareHostdev(virDomainObj *vm)
}
}
- if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) {
+ if (vm->def->iommufd_fdgroup) {
+ ignore_value(qemuProcessGetPassedIommuFd(vm));
+ } else if (virDomainDefHasPCIHostdevWithIOMMUFD(vm->def)) {
int iommufd = 0;
priv->iommufd = qemuFDPassDirectNew("iommufd", &iommufd);
}
@@ -3099,6 +3104,8 @@ mymain(void)
DO_TEST_CAPS_LATEST("iommufd");
DO_TEST_CAPS_LATEST("iommufd-q35");
+ DO_TEST_CAPS_ARCH_LATEST_FULL("iommufd-q35-fd", "x86_64",
+ ARG_FD_GROUP, "iommu", false, 1, 20);
DO_TEST_CAPS_ARCH_LATEST("iommufd-virt", "aarch64");
DO_TEST_CAPS_ARCH_LATEST("iommufd-virt-pci-bus-single", "aarch64");
--
2.54.0

127
centos-9/SOURCES/libvirt-util-Publish-and-mock-virHostCPUGetMSRFromKVM.patch

@ -0,0 +1,127 @@
From d1421d7387a3a747d3476471d7c94b294cfb2748 Mon Sep 17 00:00:00 2001
Message-ID: <d1421d7387a3a747d3476471d7c94b294cfb2748.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Mon, 25 May 2026 12:27:41 +0200
Subject: [PATCH] util: Publish and mock virHostCPUGetMSRFromKVM
The function will later be called when probing QEMU capabilities.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 3184289356bd97daa75f77bec189e5ce152ba5e6)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virhostcpu.c | 22 +++++++++++++++++++++-
src/util/virhostcpu.h | 3 +++
tests/qemucpumock.c | 22 ++++++++++++++++++++++
4 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 1733286bad..3eca15f066 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2586,6 +2586,7 @@ virHostCPUGetKVMMaxVCPUs;
virHostCPUGetMap;
virHostCPUGetMicrocodeVersion;
virHostCPUGetMSR;
+virHostCPUGetMSRFromKVM;
virHostCPUGetOnline;
virHostCPUGetOnlineBitmap;
virHostCPUGetPhysAddrSize;
diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
index 09395ddb04..a23a3f95e7 100644
--- a/src/util/virhostcpu.c
+++ b/src/util/virhostcpu.c
@@ -1329,7 +1329,18 @@ virHostCPUGetMicrocodeVersion(virArch hostArch G_GNUC_UNUSED)
#if WITH_LINUX_KVM_H && defined(KVM_GET_MSRS) && \
(defined(__i386__) || defined(__x86_64__))
-static int
+/**
+ * virHostCPUGetMSRFromKVM:
+ * @index: MSR to read
+ * @result: where to store the content of the @index register
+ *
+ * Reads the 64b content of the specified register via KVM_GET_MSRS ioctl.
+ *
+ * Returns 0 on success,
+ * 1 when the MSR is not supported by the host CPU,
+ * -1 on error.
+ */
+int
virHostCPUGetMSRFromKVM(unsigned long index,
uint64_t *result)
{
@@ -1566,6 +1577,15 @@ virHostCPUGetCPUID(void)
return NULL;
}
+int
+virHostCPUGetMSRFromKVM(unsigned long index G_GNUC_UNUSED,
+ uint64_t *result G_GNUC_UNUSED)
+{
+ virReportSystemError(ENOSYS, "%s",
+ _("Reading MSRs is not supported on this platform"));
+ return -1;
+}
+
int
virHostCPUGetMSR(unsigned long index G_GNUC_UNUSED,
uint64_t *msr G_GNUC_UNUSED)
diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h
index 289ae41439..24c7fdaf7c 100644
--- a/src/util/virhostcpu.h
+++ b/src/util/virhostcpu.h
@@ -80,6 +80,9 @@ int virHostCPUGetOnline(unsigned int cpu, bool *online);
unsigned int
virHostCPUGetMicrocodeVersion(virArch hostArch) ATTRIBUTE_MOCKABLE;
+int virHostCPUGetMSRFromKVM(unsigned long index,
+ uint64_t *result) ATTRIBUTE_MOCKABLE;
+
int virHostCPUGetMSR(unsigned long index,
uint64_t *msr);
diff --git a/tests/qemucpumock.c b/tests/qemucpumock.c
index 5a63308347..de1e79bfc1 100644
--- a/tests/qemucpumock.c
+++ b/tests/qemucpumock.c
@@ -23,6 +23,7 @@
#include "qemu/qemu_capspriv.h"
#include "testutilshostcpus.h"
#include "virarch.h"
+#include "util/virhostcpu.h"
virCPUDef *
@@ -33,3 +34,24 @@ virQEMUCapsProbeHostCPU(virArch hostArch G_GNUC_UNUSED,
return testUtilsHostCpusGetDefForModel(model);
}
+
+
+int
+virHostCPUGetMSRFromKVM(unsigned long index,
+ uint64_t *result)
+{
+ if (index == 0x10a) {
+ /* Return some arbitrary bits in arch-capabilities MSR */
+ *result =
+ 0x00000001 | /* rdctl-no */
+ 0x00000008 | /* skip-l1dfl-vmentry */
+ 0x00000020 | /* mds-no */
+ 0x00000040 | /* pschange-mc-no */
+ 0x04000000 | /* gds-no */
+ 0x08000000; /* rfds-no */
+ return 0;
+ }
+
+ errno = ENOTSUP;
+ return -1;
+}
--
2.54.0

43
centos-9/SOURCES/libvirt-util-virGetSubIDs-do-not-limit-file-size.patch

@ -0,0 +1,43 @@
From 89d55e7dc4be2177645e6090a21ce0f293feec6a Mon Sep 17 00:00:00 2001
Message-ID: <89d55e7dc4be2177645e6090a21ce0f293feec6a.1780571166.git.jdenemar@redhat.com>
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
Date: Tue, 12 May 2026 13:10:43 +0200
Subject: [PATCH] util: virGetSubIDs: do not limit file size
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On systems with many users, this file can be larger than BUFSIZ.
Since the file should only be editable by root and virFileReadAll
reallocates the buffer in increments as needed as opposed to
allocating for 'maxlen' upfront, set the maximum to INT_MAX.
https://gitlab.com/libvirt/libvirt/-/work_items/874
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit b0c104e7aaf9cde62702dd66e2c7e4343495de59)
https://redhat.atlassian.net/browse/RHEL-174491
Signed-off-by: Ján Tomko <jtomko@redhat.com>
---
src/util/virutil.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/util/virutil.c b/src/util/virutil.c
index fb64237692..94a6958582 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -1202,7 +1202,9 @@ virGetSubIDs(virSubID **retval, const char *file)
*retval = NULL;
- if (virFileReadAll(file, BUFSIZ, &buf) < 0)
+ /* We trust the source of the file so we set the limit absurdly high.
+ * For smaller files, the helper function will not allocate as much space */
+ if (virFileReadAll(file, INT_MAX, &buf) < 0)
return -1;
lines = g_strsplit(buf, "\n", 0);
--
2.54.0

79
centos-9/SOURCES/libvirt-viriommufd-Set-IOMMU_OPTION_RLIMIT_MODE-only-when-running-privileged.patch

@ -0,0 +1,79 @@
From 32ff11b8bbc74b61f5ff531f9fb5c83f1a4da343 Mon Sep 17 00:00:00 2001
Message-ID: <32ff11b8bbc74b61f5ff531f9fb5c83f1a4da343.1780571166.git.jdenemar@redhat.com>
From: Pavel Hrdina <phrdina@redhat.com>
Date: Fri, 13 Mar 2026 10:50:36 +0100
Subject: [PATCH] viriommufd: Set IOMMU_OPTION_RLIMIT_MODE only when running
privileged
If libvirt daemon is running unprivileged it will fail so we should not
even try to set it.
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 293bb59e75f4b4c975bbeccb1bb8b39b6f439a35)
Resolves: https://redhat.atlassian.net/browse/RHEL-156803
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_process.c | 2 +-
src/util/viriommufd.c | 6 +++---
src/util/viriommufd.h | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 0a69063a4b..9b8b378b1f 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -7695,7 +7695,7 @@ qemuProcessOpenIommuFd(virDomainObj *vm)
VIR_DEBUG("Opening IOMMU FD for domain %s", vm->def->name);
- if ((iommufd = virIOMMUFDOpenDevice()) < 0)
+ if ((iommufd = virIOMMUFDOpenDevice(priv->driver->privileged)) < 0)
return -1;
if (qemuSecuritySetImageFDLabel(priv->driver->securityManager, vm->def, iommufd) < 0)
diff --git a/src/util/viriommufd.c b/src/util/viriommufd.c
index b62d59241d..82920923a2 100644
--- a/src/util/viriommufd.c
+++ b/src/util/viriommufd.c
@@ -80,14 +80,14 @@ virIOMMUFDSetRLimitMode(int fd, bool processAccounting)
}
int
-virIOMMUFDOpenDevice(void)
+virIOMMUFDOpenDevice(bool privileged)
{
int fd = -1;
if ((fd = open(VIR_IOMMU_DEV_PATH, O_RDWR | O_CLOEXEC)) < 0)
virReportSystemError(errno, "%s", _("cannot open IOMMUFD device"));
- if (virIOMMUFDSetRLimitMode(fd, true) < 0) {
+ if (privileged && virIOMMUFDSetRLimitMode(fd, true) < 0) {
VIR_FORCE_CLOSE(fd);
return -1;
}
@@ -98,7 +98,7 @@ virIOMMUFDOpenDevice(void)
#else
int
-virIOMMUFDOpenDevice(void)
+virIOMMUFDOpenDevice(bool privileged G_GNUC_UNUSED)
{
virReportError(VIR_ERR_NO_SUPPORT, "%s",
_("IOMMUFD is not supported on this platform"));
diff --git a/src/util/viriommufd.h b/src/util/viriommufd.h
index 223f44eb5c..7bad5c7472 100644
--- a/src/util/viriommufd.h
+++ b/src/util/viriommufd.h
@@ -22,6 +22,6 @@
#define VIR_IOMMU_DEV_PATH "/dev/iommu"
-int virIOMMUFDOpenDevice(void);
+int virIOMMUFDOpenDevice(bool privileged);
bool virIOMMUFDSupported(void);
--
2.54.0

68
centos-9/SOURCES/libvirt-virsh-Add-expand-cpu-features-option-for-domcapabilities.patch

@ -0,0 +1,68 @@
From 169253f6cc07e089162c1350d434e8d197298f6a Mon Sep 17 00:00:00 2001
Message-ID: <169253f6cc07e089162c1350d434e8d197298f6a.1780571166.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Wed, 11 Mar 2026 12:13:22 +0100
Subject: [PATCH] virsh: Add --expand-cpu-features option for domcapabilities
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 57e5bb55cef5e97eea14fcecef7114e804576d6c)
https://issues.redhat.com/browse/RHEL-153653
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
docs/manpages/virsh.rst | 5 +++++
tools/virsh-host.c | 7 +++++++
2 files changed, 12 insertions(+)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index ff0cf1a715..85fa6ab011 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -592,6 +592,7 @@ domcapabilities
domcapabilities [virttype] [emulatorbin] [arch] [machine]
[--xpath EXPRESSION] [--wrap]
[--disable-deprecated-features]
+ [--expand-cpu-features]
Print an XML document describing the domain capabilities for the
@@ -638,6 +639,10 @@ of host-model CPU XML, updating the features list with any features
flagged as deprecated for the CPU model by the hypervisor. These
features will be paired with the "disable" policy.
+The **--expand-cpu-features** option will cause the host-model CPU definition
+to contain all CPU features supported on the host including those implicitly
+enabled by the selected CPU model.
+
pool-capabilities
-----------------
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index e918cfa4ca..dd98917fa8 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -118,6 +118,10 @@ static const vshCmdOptDef opts_domcapabilities[] = {
.type = VSH_OT_BOOL,
.help = N_("report host CPU model with deprecated features disabled"),
},
+ {.name = "expand-cpu-features",
+ .type = VSH_OT_BOOL,
+ .help = N_("show all features in host CPU model"),
+ },
{.name = NULL}
};
@@ -137,6 +141,9 @@ cmdDomCapabilities(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool(cmd, "disable-deprecated-features"))
flags |= VIR_CONNECT_GET_DOMAIN_CAPABILITIES_DISABLE_DEPRECATED_FEATURES;
+ if (vshCommandOptBool(cmd, "expand-cpu-features"))
+ flags |= VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES;
+
if (vshCommandOptString(ctl, cmd, "virttype", &virttype) < 0 ||
vshCommandOptString(ctl, cmd, "emulatorbin", &emulatorbin) < 0 ||
vshCommandOptString(ctl, cmd, "arch", &arch) < 0 ||
--
2.54.0

75
centos-9/SOURCES/libvirt-virsh-Add-supported-cpu-features-option-for-domcapabilities.patch

@ -0,0 +1,75 @@
From ec36f1c9c281c98378dd937ba60aeee60e95daaf Mon Sep 17 00:00:00 2001
Message-ID: <ec36f1c9c281c98378dd937ba60aeee60e95daaf.1780571167.git.jdenemar@redhat.com>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 29 May 2026 12:52:59 +0200
Subject: [PATCH] virsh: Add --supported-cpu-features option for
domcapabilities
The option corresponds to the
VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES API flag.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
(cherry picked from commit 26ffa1d4f0b74c7cda5a6906510cf2d6362b5b8b)
https://redhat.atlassian.net/browse/RHEL-177364
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
docs/manpages/virsh.rst | 8 +++++++-
tools/virsh-host.c | 7 +++++++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
index 7169b6bc05..2936df6a73 100644
--- a/docs/manpages/virsh.rst
+++ b/docs/manpages/virsh.rst
@@ -592,7 +592,7 @@ domcapabilities
domcapabilities [virttype] [emulatorbin] [arch] [machine]
[--xpath EXPRESSION] [--wrap]
[--disable-deprecated-features]
- [--expand-cpu-features]
+ [--expand-cpu-features] [--supported-cpu-features]
Print an XML document describing the domain capabilities for the
@@ -644,6 +644,12 @@ to contain all required CPU features including those implicitly enabled by the
selected CPU model. Without this flag features that are part of the CPU model
itself will not be listed.
+The **--supported-cpu-features** option will update the host-model CPU
+definition with features that are supported on the host, but will not be
+enabled by default when starting a domain with host-model CPU. Using both
+**--supported-cpu-features** and **--expand-cpu-features** will provide a
+complete list of features that can be enabled on the host.
+
pool-capabilities
-----------------
diff --git a/tools/virsh-host.c b/tools/virsh-host.c
index 5dbeb54ae5..4b95d2748e 100644
--- a/tools/virsh-host.c
+++ b/tools/virsh-host.c
@@ -122,6 +122,10 @@ static const vshCmdOptDef opts_domcapabilities[] = {
.type = VSH_OT_BOOL,
.help = N_("expand 'host-model' CPU to also show features enabled by the CPU model"),
},
+ {.name = "supported-cpu-features",
+ .type = VSH_OT_BOOL,
+ .help = N_("include all supported CPU features in 'host-model' mode, not only those enabled by default"),
+ },
{.name = NULL}
};
@@ -144,6 +148,9 @@ cmdDomCapabilities(vshControl *ctl, const vshCmd *cmd)
if (vshCommandOptBool(cmd, "expand-cpu-features"))
flags |= VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES;
+ if (vshCommandOptBool(cmd, "supported-cpu-features"))
+ flags |= VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES;
+
if (vshCommandOptString(ctl, cmd, "virttype", &virttype) < 0 ||
vshCommandOptString(ctl, cmd, "emulatorbin", &emulatorbin) < 0 ||
vshCommandOptString(ctl, cmd, "arch", &arch) < 0 ||
--
2.54.0

3
centos-9/SOURCES/zfs-2.2.10.tar.gz

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:988a1e499aedb03d41b9b4b73ffb8162018602a6da40ae9e1b8962c15d8f85dc
size 33868717

3
centos-9/SOURCES/zfs-2.2.8.tar.gz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:727ac0e81c5446aae76839a85ea3ea7a966ed4112421db1d0f70c1b2f92dc0c0
size 33851391

3
centos-9/SOURCES/zfs-2.2.9.tar.gz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e40d697efb8b4d1daf042852a4575a1a168cfdbb68fcd93dde7698e8b513c28c
size 33861997

89
centos-9/SPECS/libvirt.spec

@ -287,7 +287,7 @@
Summary: Library providing a simple virtualization API
Name: libvirt
Version: 11.10.0
Release: 12%{?dist}%{?extra_release}
Release: 13%{?dist}%{?extra_release}
License: GPL-2.0-or-later AND LGPL-2.1-only AND LGPL-2.1-or-later AND OFL-1.1
URL: https://libvirt.org/
@ -372,6 +372,48 @@ Patch74: libvirt-iommufd-fix-FD-leak-in-case-of-error.patch
Patch75: libvirt-domain_conf-initialize-network-hostdev-private-data.patch
Patch76: libvirt-qemu_hotplug-enter-monitor-in-order-to-rollback-passed-FD.patch
Patch77: libvirt-qemu_hotplug-Fix-crash-when-attaching-network-inteface-with-hostdev-network.patch
Patch78: libvirt-conf-Parse-hyperv-features-even-for-host-model.patch
Patch79: libvirt-qemu-Wire-up-new-hyperv-host-model-mode-behavior.patch
Patch80: libvirt-Introduce-EXPAND_CPU_FEATURES-flag-for-domain-capabilities.patch
Patch81: libvirt-qemu-Implement-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES.patch
Patch82: libvirt-virsh-Add-expand-cpu-features-option-for-domcapabilities.patch
Patch83: libvirt-docs-Clarify-host-model-description-in-domain-capabilities.patch
Patch84: libvirt-qemu-Fix-job-handling-when-domain-dies-in-post-copy-migration.patch
Patch85: libvirt-security_apparmor-Use-g_auto-in-AppArmorSetSecurityHostdevLabel.patch
Patch86: libvirt-security-Cleanup-hostdev-label-error-logic.patch
Patch87: libvirt-qemu-Fix-IOMMUFD-and-VFIO-security-labels.patch
Patch88: libvirt-viriommufd-Set-IOMMU_OPTION_RLIMIT_MODE-only-when-running-privileged.patch
Patch89: libvirt-conf-Move-and-rename-virStorageSourceFDTuple-object.patch
Patch90: libvirt-conf-Refactor-virHostdevIsPCIDevice.patch
Patch91: libvirt-hypervisor-Fix-virHostdevNeedsVFIO-detection.patch
Patch92: libvirt-qemu-Expand-call-to-qemuDomainNeedsVFIO.patch
Patch93: libvirt-qemu-Update-qemuDomainNeedsVFIO-to-ignore-PCI-hostdev-with-IOMMUFD.patch
Patch94: libvirt-src-Use-virHostdevIsPCIDeviceWith-to-check-for-IOMMUFD.patch
Patch95: libvirt-conf-Introduce-domain-iommufd-element.patch
Patch96: libvirt-qemu-Implement-iommufd.patch
Patch97: libvirt-conf-Add-iommufd-fdgroup-support.patch
Patch98: libvirt-qemu-Implement-iommufd-fdgroup.patch
Patch99: libvirt-tests-Add-iommufd-fdgroup-test.patch
Patch100: libvirt-hypervisor-Call-virWaitForDevices-after-detaching-host-devices.patch
Patch101: libvirt-qemuMigrationSrcBeginXML-Don-t-call-qemuMigrationSrcBeginPhaseBlockDirtyBitmaps-with-offline-VM.patch
Patch102: libvirt-qemuMigrationSrcBeginPhase-Don-t-call-qemuBlockNodesEnsureActive-with-offline-VM.patch
Patch103: libvirt-util-virGetSubIDs-do-not-limit-file-size.patch
Patch104: libvirt-cpu_conf-Introduce-virCPUDefSortFeatures.patch
Patch105: libvirt-qemu_capabilities-Split-virQEMUCapsFillDomainCPUCaps.patch
Patch106: libvirt-qemu-Move-domain-caps-flags-handling-to-virQEMUCapsFillDomainCPUHostModel.patch
Patch107: libvirt-qemu_capabilities-Always-sort-features-in-host-model-CPU.patch
Patch108: libvirt-qemu_capabilities-Use-g_autoptr-in-virQEMUCapsInitHostCPUModel.patch
Patch109: libvirt-qemu_capabilities-Split-conditions-in-virQEMUCapsInitHostCPUModel.patch
Patch110: libvirt-qemu_capabilities-Cache-expanded-CPU.patch
Patch111: libvirt-domaincapstest-Test-EXPAND_CPU_FEATURES-flag.patch
Patch112: libvirt-util-Publish-and-mock-virHostCPUGetMSRFromKVM.patch
Patch113: libvirt-cpu_x86-Introduce-virCPUx86DataAddMSR.patch
Patch114: libvirt-cpu-Introduce-virCPUUpdateFeatures.patch
Patch115: libvirt-Fix-documentation-of-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES.patch
Patch116: libvirt-Introduce-VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES-flag.patch
Patch117: libvirt-virsh-Add-supported-cpu-features-option-for-domcapabilities.patch
Patch118: libvirt-domaincapstest-Test-SUPPORTED_CPU_FEATURES-flag.patch
Patch119: libvirt-qemu_capabilities-Fix-domain-capabilities-on-AMD-CPUs.patch
Requires: libvirt-daemon = %{version}-%{release}
@ -2763,6 +2805,51 @@ exit 0
%endif
%changelog
* Thu Jun 4 2026 Jiri Denemark <jdenemar@redhat.com> - 11.10.0-13
- conf: Parse hyperv features even for host-model (RHEL-151688)
- qemu: Wire up new hyperv host-model mode behavior (RHEL-151688)
- Introduce EXPAND_CPU_FEATURES flag for domain capabilities (RHEL-153653)
- qemu: Implement VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES (RHEL-153653)
- virsh: Add --expand-cpu-features option for domcapabilities (RHEL-153653)
- docs: Clarify host-model description in domain capabilities (RHEL-153653)
- qemu: Fix job handling when domain dies in post-copy migration (RHEL-145179)
- security_apparmor: Use g_auto* in AppArmorSetSecurityHostdevLabel (RHEL-159902)
- security: Cleanup hostdev label error logic (RHEL-159902)
- qemu: Fix IOMMUFD and VFIO security labels (RHEL-159902)
- viriommufd: Set IOMMU_OPTION_RLIMIT_MODE only when running privileged (RHEL-156803)
- conf: Move and rename virStorageSourceFDTuple object (RHEL-156803)
- conf: Refactor virHostdevIsPCIDevice (RHEL-156803)
- hypervisor: Fix virHostdevNeedsVFIO detection (RHEL-156803)
- qemu: Expand call to qemuDomainNeedsVFIO (RHEL-156803)
- qemu: Update qemuDomainNeedsVFIO to ignore PCI hostdev with IOMMUFD (RHEL-156803)
- src: Use virHostdevIsPCIDeviceWith* to check for IOMMUFD (RHEL-156803)
- conf: Introduce domain iommufd element (RHEL-156803)
- qemu: Implement iommufd (RHEL-156803)
- conf: Add iommufd fdgroup support (RHEL-156803)
- qemu: Implement iommufd fdgroup (RHEL-156803)
- tests: Add iommufd fdgroup test (RHEL-156803)
- hypervisor: Call virWaitForDevices() after detaching host devices (RHEL-156803)
- qemuMigrationSrcBeginXML: Don't call 'qemuMigrationSrcBeginPhaseBlockDirtyBitmaps' with offline VM (RHEL-173433)
- qemuMigrationSrcBeginPhase: Don't call 'qemuBlockNodesEnsureActive' with offline VM (RHEL-173433)
- util: virGetSubIDs: do not limit file size (RHEL-174491)
- cpu_conf: Introduce virCPUDefSortFeatures (RHEL-177364)
- qemu_capabilities: Split virQEMUCapsFillDomainCPUCaps (RHEL-177364)
- qemu: Move domain caps flags handling to virQEMUCapsFillDomainCPUHostModel (RHEL-177364)
- qemu_capabilities: Always sort features in host-model CPU (RHEL-177364)
- qemu_capabilities: Use g_autoptr in virQEMUCapsInitHostCPUModel (RHEL-177364)
- qemu_capabilities: Split conditions in virQEMUCapsInitHostCPUModel (RHEL-177364)
- qemu_capabilities: Cache expanded CPU (RHEL-177364)
- domaincapstest: Test EXPAND_CPU_FEATURES flag (RHEL-177364)
- util: Publish and mock virHostCPUGetMSRFromKVM (RHEL-177364)
- cpu_x86: Introduce virCPUx86DataAddMSR (RHEL-177364)
- cpu: Introduce virCPUUpdateFeatures (RHEL-177364)
- Fix documentation of VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES (RHEL-177364)
- Introduce VIR_CONNECT_GET_DOMAIN_CAPABILITIES_SUPPORTED_CPU_FEATURES flag (RHEL-177364)
- virsh: Add --supported-cpu-features option for domcapabilities (RHEL-177364)
- domaincapstest: Test SUPPORTED_CPU_FEATURES flag (RHEL-177364)
- qemu_capabilities: Fix domain capabilities on AMD CPUs (RHEL-177364)
- distro: Replace old gating with tmt
* Tue Mar 10 2026 Jiri Denemark <jdenemar@redhat.com> - 11.10.0-12
- qemu_hotplug: Fix crash when attaching network inteface with hostdev network (RHEL-151953)

4
centos-9/SPECS/zfs-dkms.spec

@ -12,8 +12,8 @@
Name: %{module}-dkms
Version: 2.2.9
Release: 3%{?dist}
Version: 2.2.10
Release: 1%{?dist}
Summary: Kernel module(s) (dkms)
Group: System Environment/Kernel

5
centos-9/SPECS/zfs.spec

@ -90,8 +90,8 @@
%define __python_sitelib %(%{__python} -Esc "from distutils.sysconfig import get_python_lib; print(get_python_lib())" 2>/dev/null || %{__python} -Esc "import sysconfig; print(sysconfig.get_path('purelib'))")
Name: zfs
Version: 2.2.9
Release: 3%{?dist}
Version: 2.2.10
Release: 1%{?dist}
Summary: Commands to control the kernel modules and libraries
Group: System Environment/Kernel
@ -529,7 +529,6 @@ systemctl --system daemon-reload >/dev/null || true
%config(noreplace) %{_sysconfdir}/%{name}/zed.d/*
%config(noreplace) %{_sysconfdir}/%{name}/zpool.d/*
%config(noreplace) %{_sysconfdir}/%{name}/vdev_id.conf.*.example
%attr(440, root, root) %config(noreplace) %{_sysconfdir}/sudoers.d/*
%config(noreplace) %{_bashcompletiondir}/zfs
%config(noreplace) %{_bashcompletiondir}/zpool

91
common.sh

@ -0,0 +1,91 @@
# Common code shared between build.sh and update.sh
# Prints the list of currently maintained Fedora versions (e.g. "42 43 44"),
# based on the Bodhi releases API.
function get_fedora_versions () {
curl -fsSL "https://bodhi.fedoraproject.org/releases/?exclude_archived=true&state=current" \
| jq -r '.releases[] | select(.id_prefix=="FEDORA") | .version' \
| grep -E '^[0-9]+$' | sort -n
}
# Prints the list of active CentOS Stream versions (e.g. "9 10"),
# based on the directory listing of the official mirror.
function get_centos_stream_versions () {
curl -fsSL "https://mirror.stream.centos.org/" \
| grep -oP '(?<=href=")[0-9]+-stream(?=/")' \
| sed 's/-stream//' | sort -n
}
# Prints the list of currently maintained Fedora and CentOS Stream versions (e.g. "centos-9 centos-10 fedora-42 fedora-43 fedora-44").
function get_all_remote_dists () {
local dists=()
for v in $(get_centos_stream_versions); do
dists+=("centos-$v")
done
for v in $(get_fedora_versions); do
dists+=("fedora-$v")
done
echo "${dists[@]}"
}
# Installs locally all source RPMs of a given distribution.
function install_all_srpm () {
local dist=$1
echo "Importing source RPMs of $dist..."
rpm -ivh "--define=_topdir $PWD/$dist" "$dist/SRPMS/"*.src.rpm
}
# Applies all patches for a given distribution.
function apply_patches () {
local dist=$1
for patch in "$dist/PATCHES"/*.patch; do
echo "Applying patch $(basename "$patch")..."
patch -d "$dist"* -p1 < "$patch"
done
}
# Downloads the libvirt and zfs source RPMs for a given Fedora distribution.
function download_sources_fedora () {
local dist=$1
local v="${dist#*-}"
echo "Downloading libvirt source for Fedora $v..."
dnf download --repofrompath=$dist,https://dl.fedoraproject.org/pub/fedora/linux/releases/$v/Everything/source/tree/ --repofrompath=$dist-updates,https://dl.fedoraproject.org/pub/fedora/linux/updates/$v/Everything/source/tree/ --repo="$dist" --repo="$dist-updates" --source libvirt --destdir $dist/SRPMS/
echo "Downloading zfs source for Fedora $v..."
if ! dnf download --repofrompath=zfs-$dist,http://download.zfsonlinux.org/fedora/$v/SRPMS/ --repo=zfs-$dist --source zfs zfs-dkms --destdir $dist/SRPMS/; then
echo "ZFS source RPM not found for Fedora $v, skipping..."
fi
}
# Downloads the libvirt and zfs source RPMs for a given CentOS Stream distribution.
function download_sources_centos_stream () {
local dist=$1
local v="${dist#*-}"
echo "Downloading libvirt source for CentOS Stream $v..."
dnf download --repofrompath=$dist,https://mirror.stream.centos.org/$v-stream/AppStream/source/tree/ --repo="$dist" --source libvirt --destdir $dist/SRPMS/
echo "Downloading zfs source for CentOS Stream $v..."
if ! dnf download --repofrompath=zfs-$dist,http://download.zfsonlinux.org/epel/$v/SRPMS/ --repo=zfs-$dist --source zfs zfs-dkms --destdir $dist/SRPMS/; then
echo "ZFS source RPM not found for CentOS Stream $v, skipping..."
fi
}
# Prints the latest Fedora version for which zfs source RPMs are published on
# download.zfsonlinux.org. This is not necessarily the latest Fedora version.
function get_latest_zfs_fedora_version () {
curl -fsSL "http://download.zfsonlinux.org/fedora/" \
| grep -oP '(?<=href=")[0-9]+(?=/")' | sort -n | tail -1
}
# Downloads the libvirt source RPM from Fedora Rawhide and the zfs source RPMs
# from the latest Fedora version published on download.zfsonlinux.org (which
# may lag behind Rawhide).
function download_sources_fedora_rawhide () {
local dist=$1
echo "Downloading libvirt source for Fedora Rawhide..."
dnf download --repofrompath=$dist,https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Everything/source/tree/ --repo="$dist" --source libvirt --destdir $dist/SRPMS/
local zfs_version
zfs_version="$(get_latest_zfs_fedora_version)"
echo "Downloading zfs source from Fedora $zfs_version (latest available on download.zfsonlinux.org)..."
if ! dnf download --repofrompath=zfs-$dist,http://download.zfsonlinux.org/fedora/$zfs_version/SRPMS/ --repo=zfs-$dist --source zfs zfs-dkms --destdir $dist/SRPMS/; then
echo "ZFS source RPM not found for Fedora $zfs_version, skipping..."
fi
}

29
fedora-41/SOURCES/0001-virarptable-Properly-calculate-rtattr-length.patch

@ -1,29 +0,0 @@
From: Martin Kletzander <mkletzan@redhat.com>
Date: Fri, 16 Aug 2024 13:56:51 +0200
Subject: [PATCH] virarptable: Properly calculate rtattr length
Content-type: text/plain
Use convenience macro which does almost the same thing we were doing,
but also pads out the payload length to a multiple of NLMSG_ALIGNTO (4)
bytes.
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
---
src/util/virarptable.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/util/virarptable.c b/src/util/virarptable.c
index 299dddd664..d8e41c5a86 100644
--- a/src/util/virarptable.c
+++ b/src/util/virarptable.c
@@ -102,8 +102,7 @@ virArpTableGet(void)
return table;
VIR_WARNINGS_NO_CAST_ALIGN
- parse_rtattr(tb, NDA_MAX, NDA_RTA(r),
- nh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
+ parse_rtattr(tb, NDA_MAX, NDA_RTA(r), NLMSG_PAYLOAD(nh, sizeof(*r)));
VIR_WARNINGS_RESET
if (tb[NDA_DST] == NULL || tb[NDA_LLADDR] == NULL)

34
fedora-41/SOURCES/0002-virarptable-Fix-check-for-message-length.patch

@ -1,34 +0,0 @@
From: Martin Kletzander <mkletzan@redhat.com>
Date: Fri, 16 Aug 2024 13:59:15 +0200
Subject: [PATCH] virarptable: Fix check for message length
Content-type: text/plain
The previous check was all wrong since it calculated the how long would
the netlink message be if the netlink header was the payload and then
subtracted that from the whole message length, a variable that was not
used later in the code. This check can fail if there are no additional
payloads, struct rtattr in particular, which we are parsing later,
however the RTA_OK macro would've caught that anyway.
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
---
src/util/virarptable.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/util/virarptable.c b/src/util/virarptable.c
index d8e41c5a86..45ee76766f 100644
--- a/src/util/virarptable.c
+++ b/src/util/virarptable.c
@@ -81,10 +81,9 @@ virArpTableGet(void)
for (; NLMSG_OK(nh, msglen); nh = NLMSG_NEXT(nh, msglen)) {
VIR_WARNINGS_RESET
struct ndmsg *r = NLMSG_DATA(nh);
- int len = nh->nlmsg_len;
void *addr;
- if ((len -= NLMSG_LENGTH(sizeof(*nh))) < 0) {
+ if (nh->nlmsg_len < NLMSG_SPACE(sizeof(*r))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("wrong nlmsg len"));
goto cleanup;

46
fedora-41/SOURCES/0003-virarptable-End-parsing-earlier-in-case-of-NLMSG_DON.patch

@ -1,46 +0,0 @@
From: Martin Kletzander <mkletzan@redhat.com>
Date: Fri, 16 Aug 2024 14:02:48 +0200
Subject: [PATCH] virarptable: End parsing earlier in case of NLMSG_DONE
Content-type: text/plain
Check for the last multipart message right as the first thing. The
presumption probably was that the last message might still contain a
payload we want to parse. However that cannot be true since that would
have to be a type RTM_NEWNEIGH. This was not caught because older
kernels were note sending NLMSG_DONE and probably relied on the fact
that the parsing just stops after all the messages are walked through,
which the NLMSG_OK macro successfully did.
Resolves: https://issues.redhat.com/browse/RHEL-52449
Resolves: https://bugzilla.redhat.com/2302245
Fixes: a176d67cdfaf5b8237a7e3a80d8be0e6bdf2d8fd
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Laine Stump <laine@redhat.com>
---
src/util/virarptable.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/util/virarptable.c b/src/util/virarptable.c
index 45ee76766f..20d11f97b0 100644
--- a/src/util/virarptable.c
+++ b/src/util/virarptable.c
@@ -83,6 +83,9 @@ virArpTableGet(void)
struct ndmsg *r = NLMSG_DATA(nh);
void *addr;
+ if (nh->nlmsg_type == NLMSG_DONE)
+ break;
+
if (nh->nlmsg_len < NLMSG_SPACE(sizeof(*r))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("wrong nlmsg len"));
@@ -97,9 +100,6 @@ virArpTableGet(void)
(!(r->ndm_state == NUD_STALE || r->ndm_state == NUD_REACHABLE)))
continue;
- if (nh->nlmsg_type == NLMSG_DONE)
- return table;
-
VIR_WARNINGS_NO_CAST_ALIGN
parse_rtattr(tb, NDA_MAX, NDA_RTA(r), NLMSG_PAYLOAD(nh, sizeof(*r)));
VIR_WARNINGS_RESET

315
fedora-41/SOURCES/0004-util-use-a-single-flags-arg-for-virNetDevBandwidthSe.patch

@ -1,315 +0,0 @@
From 807e2670f2704c41f0a1dca81a5d2f2f9336137c Mon Sep 17 00:00:00 2001
From: Laine Stump <laine@redhat.com>
Date: Mon, 25 Nov 2024 22:24:44 -0500
Subject: [PATCH 4/9] util: use a single flags arg for virNetDevBandwidthSet(),
not multiple bools
Having two bools in the arg list is on the borderline of being
confusing to anyone trying to read the code, but we're about to add a
3rd. This patch replaces the two bools with a single flags argument
which will instead have one or more bits from virNetDevBandwidthFlags
set.
Signed-off-by: Laine Stump <laine@redhat.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
src/lxc/lxc_driver.c | 8 ++++++--
src/lxc/lxc_process.c | 8 ++++++--
src/network/bridge_driver.c | 10 ++++++++--
src/qemu/qemu_command.c | 11 ++++++++---
src/qemu/qemu_driver.c | 29 ++++++++++++++-------------
src/qemu/qemu_hotplug.c | 22 +++++++++++++++------
src/util/virnetdevbandwidth.c | 36 ++++++++++++++++++++--------------
src/util/virnetdevbandwidth.h | 9 +++++++--
tests/virnetdevbandwidthtest.c | 8 +++++++-
9 files changed, 94 insertions(+), 47 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 534e257f30..b693980dbb 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -3570,8 +3570,12 @@ lxcDomainAttachDeviceNetLive(virLXCDriver *driver,
actualBandwidth = virDomainNetGetActualBandwidth(net);
if (actualBandwidth) {
if (virNetDevSupportsBandwidth(actualType)) {
- if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false,
- !virDomainNetTypeSharesHostView(net)) < 0)
+ unsigned int flags = 0;
+
+ if (!virDomainNetTypeSharesHostView(net))
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, flags) < 0)
goto cleanup;
} else {
VIR_WARN("setting bandwidth on interfaces of "
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index f5eb5383ec..0e689fbb70 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -605,8 +605,12 @@ virLXCProcessSetupInterfaces(virLXCDriver *driver,
actualBandwidth = virDomainNetGetActualBandwidth(net);
if (actualBandwidth) {
if (virNetDevSupportsBandwidth(type)) {
- if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false,
- !virDomainNetTypeSharesHostView(net)) < 0)
+ unsigned int flags = 0;
+
+ if (!virDomainNetTypeSharesHostView(net))
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, flags) < 0)
goto cleanup;
} else {
VIR_WARN("setting bandwidth on interfaces of "
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 32572c755f..1c53636450 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -2058,8 +2058,11 @@ networkStartNetworkVirtual(virNetworkDriverState *driver,
}
}
- if (virNetDevBandwidthSet(def->bridge, def->bandwidth, true, true) < 0)
+ if (virNetDevBandwidthSet(def->bridge, def->bandwidth,
+ VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS
+ | VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED) < 0) {
goto error;
+ }
return 0;
@@ -2141,8 +2144,11 @@ networkStartNetworkBridge(virNetworkObj *obj)
* type BRIDGE, is started. On failure, undo anything you've done,
* and return -1. On success return 0.
*/
- if (virNetDevBandwidthSet(def->bridge, def->bandwidth, true, true) < 0)
+ if (virNetDevBandwidthSet(def->bridge, def->bandwidth,
+ VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS
+ | VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED) < 0) {
goto error;
+ }
if (networkStartHandleMACTableManagerMode(obj) < 0)
goto error;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index f15e6bda1e..b4815e5e71 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8840,9 +8840,14 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver,
def->uuid,
!virDomainNetTypeSharesHostView(net)) < 0)
goto cleanup;
- } else if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false,
- !virDomainNetTypeSharesHostView(net)) < 0) {
- goto cleanup;
+ } else {
+ unsigned int flags = 0;
+
+ if (!virDomainNetTypeSharesHostView(net))
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, flags) < 0)
+ goto cleanup;
}
} else {
VIR_WARN("setting bandwidth on interfaces of "
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 736602333e..14929616e5 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9941,21 +9941,22 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
virErrorRestore(&orig_err);
goto endjob;
}
- } else if (virNetDevBandwidthSet(net->ifname, newBandwidth, false,
- !virDomainNetTypeSharesHostView(net)) < 0) {
- virErrorPtr orig_err;
-
- virErrorPreserveLast(&orig_err);
- ignore_value(virNetDevBandwidthSet(net->ifname,
- net->bandwidth,
- false,
- !virDomainNetTypeSharesHostView(net)));
- if (net->bandwidth) {
- ignore_value(virDomainNetBandwidthUpdate(net,
- net->bandwidth));
+ } else {
+ unsigned int bwflags = 0;
+
+ if (!virDomainNetTypeSharesHostView(net))
+ bwflags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+
+ if (virNetDevBandwidthSet(net->ifname, newBandwidth, bwflags) < 0) {
+ virErrorPtr orig_err;
+
+ virErrorPreserveLast(&orig_err);
+ ignore_value(virNetDevBandwidthSet(net->ifname, net->bandwidth, bwflags));
+ if (net->bandwidth)
+ ignore_value(virDomainNetBandwidthUpdate(net, net->bandwidth));
+ virErrorRestore(&orig_err);
+ goto endjob;
}
- virErrorRestore(&orig_err);
- goto endjob;
}
/* If the old bandwidth was cleared out, restore qdisc. */
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 7cb1800504..d5e7e99359 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1279,9 +1279,14 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
vm->def->uuid,
!virDomainNetTypeSharesHostView(net)) < 0)
goto cleanup;
- } else if (virNetDevBandwidthSet(net->ifname, actualBandwidth, false,
- !virDomainNetTypeSharesHostView(net)) < 0) {
- goto cleanup;
+ } else {
+ int flags = 0;
+
+ if (!virDomainNetTypeSharesHostView(net))
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+
+ if (virNetDevBandwidthSet(net->ifname, actualBandwidth, flags) < 0)
+ goto cleanup;
}
} else {
VIR_WARN("setting bandwidth on interfaces of "
@@ -4082,9 +4087,14 @@ qemuDomainChangeNet(virQEMUDriver *driver,
vm->def->uuid,
!virDomainNetTypeSharesHostView(newdev)) < 0)
goto cleanup;
- } else if (virNetDevBandwidthSet(newdev->ifname, newb, false,
- !virDomainNetTypeSharesHostView(newdev)) < 0) {
- goto cleanup;
+ } else {
+ int flags = 0;
+
+ if (!virDomainNetTypeSharesHostView(newdev))
+ flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+
+ if (virNetDevBandwidthSet(newdev->ifname, newb, flags) < 0)
+ goto cleanup;
}
} else {
if (virDomainInterfaceClearQoS(vm->def, olddev) < 0)
diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c
index 2b58c58d3e..1baad849c6 100644
--- a/src/util/virnetdevbandwidth.c
+++ b/src/util/virnetdevbandwidth.c
@@ -173,30 +173,35 @@ virNetDevBandwidthManipulateFilter(const char *ifname,
* virNetDevBandwidthSet:
* @ifname: on which interface
* @bandwidth: rates to set (may be NULL)
- * @hierarchical_class: whether to create hierarchical class
- * @swapped: true if IN/OUT should be set contrariwise
+ * @flags: bits indicating certain optional actions
*
+
* This function enables QoS on specified interface
* and set given traffic limits for both, incoming
- * and outgoing traffic. Any previous setting get
- * overwritten. If @hierarchical_class is TRUE, create
- * hierarchical class. It is used to guarantee minimal
- * throughput ('floor' attribute in NIC).
+ * and outgoing traffic.
+ *
+ * @flags bits and their meanings:
+ *
+ * VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS
+ * whether to create a hierarchical class
+ * A hiearchical class structure is used to implement a minimal
+ * throughput guarantee ('floor' attribute in NIC).
*
- * If @swapped is set, the IN part of @bandwidth is set on
- * @ifname's TX, and vice versa. If it is not set, IN is set on
- * RX and OUT on TX. This is because for some types of interfaces
- * domain and the host live on the same side of the interface (so
- * domain's RX/TX is host's RX/TX), and for some it's swapped
- * (domain's RX/TX is hosts's TX/RX).
+ * VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED
+ * set if IN/OUT should be set backwards from what's indicated in
+ * the bandwidth, i.e. the IN part of @bandwidth is set on
+ * @ifname's TX, and the OUT part of @bandwidth is set on
+ * @ifname's RX. This is needed because for some types of
+ * interfaces the domain and the host live on the same side of the
+ * interface (so domain's RX/TX is host's RX/TX), and for some
+ * it's swapped (domain's RX/TX is hosts's TX/RX).
*
* Return 0 on success, -1 otherwise.
*/
int
virNetDevBandwidthSet(const char *ifname,
const virNetDevBandwidth *bandwidth,
- bool hierarchical_class,
- bool swapped)
+ unsigned int flags)
{
int ret = -1;
virNetDevBandwidthRate *rx = NULL; /* From domain POV */
@@ -205,6 +210,7 @@ virNetDevBandwidthSet(const char *ifname,
char *average = NULL;
char *peak = NULL;
char *burst = NULL;
+ bool hierarchical_class = flags & VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS;
if (!bandwidth) {
/* nothing to be enabled */
@@ -224,7 +230,7 @@ virNetDevBandwidthSet(const char *ifname,
return -1;
}
- if (swapped) {
+ if (flags & VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED) {
rx = bandwidth->out;
tx = bandwidth->in;
} else {
diff --git a/src/util/virnetdevbandwidth.h b/src/util/virnetdevbandwidth.h
index 6d268fb119..80dc654486 100644
--- a/src/util/virnetdevbandwidth.h
+++ b/src/util/virnetdevbandwidth.h
@@ -39,11 +39,16 @@ void virNetDevBandwidthFree(virNetDevBandwidth *def);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNetDevBandwidth, virNetDevBandwidthFree);
+typedef enum {
+ VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS = (1 << 0),
+ VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED = (1 << 1),
+} virNetDevBandwidthSetFlags;
+
int virNetDevBandwidthSet(const char *ifname,
const virNetDevBandwidth *bandwidth,
- bool hierarchical_class,
- bool swapped)
+ unsigned int flags)
G_GNUC_WARN_UNUSED_RESULT;
+
int virNetDevBandwidthClear(const char *ifname);
int virNetDevBandwidthCopy(virNetDevBandwidth **dest,
const virNetDevBandwidth *src)
diff --git a/tests/virnetdevbandwidthtest.c b/tests/virnetdevbandwidthtest.c
index f7c38faa2e..6529ff4026 100644
--- a/tests/virnetdevbandwidthtest.c
+++ b/tests/virnetdevbandwidthtest.c
@@ -82,8 +82,14 @@ testVirNetDevBandwidthSet(const void *data)
if (virNetDevOpenvswitchInterfaceSetQos(iface, band, info->uuid, true) < 0)
return -1;
} else {
+ unsigned int flags = VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+
+ if (info->hierarchical_class)
+ flags |= VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS;
+
exp_cmd = info->exp_cmd_tc;
- if (virNetDevBandwidthSet(iface, band, info->hierarchical_class, true) < 0)
+
+ if (virNetDevBandwidthSet(iface, band, flags) < 0)
return -1;
}
--
2.47.1

185
fedora-41/SOURCES/0005-util-make-it-optional-to-clear-existing-tc-qdiscs-fi.patch

@ -1,185 +0,0 @@
From 490f58382dca2a415a5f16b6133f298d853bb379 Mon Sep 17 00:00:00 2001
From: Laine Stump <laine@redhat.com>
Date: Mon, 25 Nov 2024 22:24:45 -0500
Subject: [PATCH 5/9] util: make it optional to clear existing tc
qdiscs/filters in virNetDevBandwidthSet()
virNetDevBandwidthSet() always clears all existing qdiscs and their
subordinate filters before adding all the new qdiscs/filters. This is
normally exactly what we want, but there is one case (the network
driver) where the Qdisc added by virNetDevBandwidthSet() may already
be in use by the nftables backend (which will add a rule to fix the
checksum of dhcp packets); in that case, we *don't* want
virNetDevBandwidthSet() to clear out the qdisc that was already added
for nftables, and none of the bandwidth filters have been added yet,
so there already aren't any "old" filters that need to be removed
either - it is safe to just skip virNetDevBandwidthClear() in this
case.
To allow the network driver to set bandwidth without first clearing
it, this patch adds the flag VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL to the
virNetDevBandwidthSetFlags enum, and recognizes it in
virNetDevBandwidthSet() - if the flag is set, then
virNetDevBandwidth() will call virNetDevBandwidthClear() just as it
always has. But if the flag isn't set it *won't* call
virNetDevBandwidthClear().
As suggested above, VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL is set for all
calls to virNetdevBandwidthSet() except for two places in the network
driver.
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
src/lxc/lxc_driver.c | 2 +-
src/lxc/lxc_process.c | 2 +-
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_driver.c | 2 +-
src/qemu/qemu_hotplug.c | 4 ++--
src/util/virnetdevbandwidth.c | 21 ++++++++++++++++++++-
src/util/virnetdevbandwidth.h | 1 +
tests/virnetdevbandwidthtest.c | 3 ++-
8 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index b693980dbb..81581c74df 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -3570,7 +3570,7 @@ lxcDomainAttachDeviceNetLive(virLXCDriver *driver,
actualBandwidth = virDomainNetGetActualBandwidth(net);
if (actualBandwidth) {
if (virNetDevSupportsBandwidth(actualType)) {
- unsigned int flags = 0;
+ unsigned int flags = VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL;
if (!virDomainNetTypeSharesHostView(net))
flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 0e689fbb70..081ce03a57 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -605,7 +605,7 @@ virLXCProcessSetupInterfaces(virLXCDriver *driver,
actualBandwidth = virDomainNetGetActualBandwidth(net);
if (actualBandwidth) {
if (virNetDevSupportsBandwidth(type)) {
- unsigned int flags = 0;
+ unsigned int flags = VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL;
if (!virDomainNetTypeSharesHostView(net))
flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index b4815e5e71..ed54fd4c5b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8841,7 +8841,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver,
!virDomainNetTypeSharesHostView(net)) < 0)
goto cleanup;
} else {
- unsigned int flags = 0;
+ unsigned int flags = VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL;
if (!virDomainNetTypeSharesHostView(net))
flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 14929616e5..9549065b1f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9942,7 +9942,7 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom,
goto endjob;
}
} else {
- unsigned int bwflags = 0;
+ unsigned int bwflags = VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL;
if (!virDomainNetTypeSharesHostView(net))
bwflags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index d5e7e99359..ceda4119cd 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1280,7 +1280,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver,
!virDomainNetTypeSharesHostView(net)) < 0)
goto cleanup;
} else {
- int flags = 0;
+ int flags = VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL;
if (!virDomainNetTypeSharesHostView(net))
flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
@@ -4088,7 +4088,7 @@ qemuDomainChangeNet(virQEMUDriver *driver,
!virDomainNetTypeSharesHostView(newdev)) < 0)
goto cleanup;
} else {
- int flags = 0;
+ int flags = VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL;
if (!virDomainNetTypeSharesHostView(newdev))
flags |= VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c
index 1baad849c6..9c48844c5d 100644
--- a/src/util/virnetdevbandwidth.c
+++ b/src/util/virnetdevbandwidth.c
@@ -196,6 +196,21 @@ virNetDevBandwidthManipulateFilter(const char *ifname,
* interface (so domain's RX/TX is host's RX/TX), and for some
* it's swapped (domain's RX/TX is hosts's TX/RX).
*
+ * VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL
+ * If VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL is set, then the root
+ * qdisc is deleted before adding any new qdisc/class/filter,
+ * which causes any pre-existing filters to also be deleted. If
+ * not set, then it's assumed that there are no existing rules (or
+ * that those already there need to be kept). The caller should
+ * set this flag for an existing interface that is having its
+ * bandwidth settings modified, but can leave it unset if the
+ * interface was newly created and this is the first time
+ * bandwidth has been set, but someone else might have already
+ * added the qdisc (e.g. this is the case when the network driver
+ * is setting bandwidth for a virtual network bridge device - the
+ * nftables backend may have already added qdisc handle 1:0 and a
+ * filter, and we don't want to delete them)
+ *
* Return 0 on success, -1 otherwise.
*/
int
@@ -238,7 +253,11 @@ virNetDevBandwidthSet(const char *ifname,
tx = bandwidth->out;
}
- virNetDevBandwidthClear(ifname);
+ /* Only if the caller requests, clear everything including root
+ * qdisc and all filters before adding everything.
+ */
+ if (flags & VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL)
+ virNetDevBandwidthClear(ifname);
if (tx && tx->average) {
average = g_strdup_printf("%llukbps", tx->average);
diff --git a/src/util/virnetdevbandwidth.h b/src/util/virnetdevbandwidth.h
index 80dc654486..744aa4c826 100644
--- a/src/util/virnetdevbandwidth.h
+++ b/src/util/virnetdevbandwidth.h
@@ -42,6 +42,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNetDevBandwidth, virNetDevBandwidthFree);
typedef enum {
VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS = (1 << 0),
VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED = (1 << 1),
+ VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL = (1 << 2),
} virNetDevBandwidthSetFlags;
int virNetDevBandwidthSet(const char *ifname,
diff --git a/tests/virnetdevbandwidthtest.c b/tests/virnetdevbandwidthtest.c
index 6529ff4026..6d5c847ad7 100644
--- a/tests/virnetdevbandwidthtest.c
+++ b/tests/virnetdevbandwidthtest.c
@@ -82,7 +82,8 @@ testVirNetDevBandwidthSet(const void *data)
if (virNetDevOpenvswitchInterfaceSetQos(iface, band, info->uuid, true) < 0)
return -1;
} else {
- unsigned int flags = VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED;
+ unsigned int flags = VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED |
+ VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL;
if (info->hierarchical_class)
flags |= VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS;
--
2.47.1

98
fedora-41/SOURCES/0006-util-put-the-command-that-adds-a-tx-filter-qdisc-int.patch

@ -1,98 +0,0 @@
From faebbbbfa3b1bd4120852b3f416c8073ab82d5c5 Mon Sep 17 00:00:00 2001
From: Laine Stump <laine@redhat.com>
Date: Mon, 25 Nov 2024 22:24:46 -0500
Subject: [PATCH 6/9] util: put the command that adds a tx filter qdisc into a
separate function
virNetDevBandwidthSet() adds a queue discipline (qdisc) for each
interface that it will need to add tc transmit filters to, and the
filters are then attached to the qdisc.
There are other circumstances where some other function will need to
add tc transmit filters to an interface (in particular an upcoming
patch to the network driver nftables backend that will use a tc tx
filter to fix the checksum of dhcp packets), so that function will
also need a qdisc for the tx filter. To assure both always use exactly
the same qdisc, this patch puts the command that adds the tx filter
qdisc into a separate helper function that can (and will) be called
from either place
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virnetdevbandwidth.c | 30 +++++++++++++++++++++++++-----
src/util/virnetdevbandwidth.h | 3 +++
3 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d15d6a6a9d..0211cee967 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2859,6 +2859,7 @@ virNetDevVFInterfaceStats;
# util/virnetdevbandwidth.h
+virNetDevBandWidthAddTxFilterParentQdisc;
virNetDevBandwidthClear;
virNetDevBandwidthCopy;
virNetDevBandwidthEqual;
diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c
index 9c48844c5d..90eebe6576 100644
--- a/src/util/virnetdevbandwidth.c
+++ b/src/util/virnetdevbandwidth.c
@@ -266,11 +266,7 @@ virNetDevBandwidthSet(const char *ifname,
if (tx->burst)
burst = g_strdup_printf("%llukb", tx->burst);
- cmd = virCommandNew(TC);
- virCommandAddArgList(cmd, "qdisc", "add", "dev", ifname, "root",
- "handle", "1:", "htb", "default",
- hierarchical_class ? "2" : "1", NULL);
- if (virCommandRun(cmd, NULL) < 0)
+ if (virNetDevBandWidthAddTxFilterParentQdisc(ifname, hierarchical_class) < 0)
goto cleanup;
/* If we are creating a hierarchical class, all non guaranteed traffic
@@ -794,3 +790,27 @@ virNetDevBandwidthSetRootQDisc(const char *ifname,
return 0;
}
+
+/**
+ * virNetDevBandwidthAddTxFilterParentQdisc:
+ * @ifname: name of interface that needs a qdisc to attach tx filters to
+ * @hierarchical_class: true if hierarchical classes will be used on this interface
+ *
+ * Add a root Qdisc (Queueing Discipline) for attaching Tx filters to
+ * @ifname.
+ *
+ * returns 0 on success, -1 on failure
+ */
+int
+virNetDevBandWidthAddTxFilterParentQdisc(const char *ifname,
+ bool hierarchical_class)
+{
+ g_autoptr(virCommand) cmd = NULL;
+
+ cmd = virCommandNew(TC);
+ virCommandAddArgList(cmd, "qdisc", "add", "dev", ifname, "root",
+ "handle", "1:", "htb", "default",
+ hierarchical_class ? "2" : "1", NULL);
+
+ return virCommandRun(cmd, NULL);
+}
diff --git a/src/util/virnetdevbandwidth.h b/src/util/virnetdevbandwidth.h
index 744aa4c826..65c1500637 100644
--- a/src/util/virnetdevbandwidth.h
+++ b/src/util/virnetdevbandwidth.h
@@ -84,3 +84,6 @@ int virNetDevBandwidthUpdateFilter(const char *ifname,
int virNetDevBandwidthSetRootQDisc(const char *ifname,
const char *qdisc)
G_NO_INLINE;
+
+int virNetDevBandWidthAddTxFilterParentQdisc(const char *ifname,
+ bool hierarchical_class);
--
2.47.1

107
fedora-41/SOURCES/0007-util-don-t-re-add-the-qdisc-used-for-tx-filters-if-i.patch

@ -1,107 +0,0 @@
From 73c0fb19ce5b816ee81ede691252855c75391c9a Mon Sep 17 00:00:00 2001
From: Laine Stump <laine@redhat.com>
Date: Mon, 25 Nov 2024 22:24:47 -0500
Subject: [PATCH 7/9] util: don't re-add the qdisc used for tx filters if it
already exists
There will soon be two separate users of tc on virtual networks, and
both will use the "qdisc root handle 1: htb" to add tx filters. One or the
other could get the first chance to add the qdisc, and then if at a
later time the other decides to use it, we need to prevent the 2nd
user from attempting to re-add the qdisc (because that just generates
an error).
We do this by running "tc qdisc show dev $bridge handle 1:" then
checking if the output of that command contains both "qdisc" and " 1:
".[*] If it does then the qdisc has already been added. If not then we
need to add it now.
[*]As of this writing, the output more exactly starts with "qdisc
htb 1: root", but our comparison is made purposefully generous to
increase the chances that it will continue to work properly if tc
modifies the format of its output.
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
src/util/virnetdevbandwidth.c | 35 ++++++++++++++++++++++++++++------
tests/virnetdevbandwidthtest.c | 3 +++
2 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c
index 90eebe6576..5c6a65528c 100644
--- a/src/util/virnetdevbandwidth.c
+++ b/src/util/virnetdevbandwidth.c
@@ -805,12 +805,35 @@ int
virNetDevBandWidthAddTxFilterParentQdisc(const char *ifname,
bool hierarchical_class)
{
- g_autoptr(virCommand) cmd = NULL;
+ g_autoptr(virCommand) testCmd = NULL;
+ g_autofree char *testResult = NULL;
- cmd = virCommandNew(TC);
- virCommandAddArgList(cmd, "qdisc", "add", "dev", ifname, "root",
- "handle", "1:", "htb", "default",
- hierarchical_class ? "2" : "1", NULL);
+ /* first check it the qdisc with handle 1: was already added for
+ * this interface by someone else
+ */
+ testCmd = virCommandNew(TC);
+ virCommandAddArgList(testCmd, "qdisc", "show", "dev", ifname,
+ "handle", "1:", NULL);
+ virCommandSetOutputBuffer(testCmd, &testResult);
- return virCommandRun(cmd, NULL);
+ if (virCommandRun(testCmd, NULL) < 0)
+ return -1;
+
+ /* output will be something like: "qdisc htb 1: root refcnt ..."
+ * if the qdisc was already added. We just search for "qdisc" and
+ * " 1: " anywhere in the output to allow for tc changing its
+ * output format.
+ */
+ if (!(testResult && strstr(testResult, "qdisc") && strstr(testResult, " 1: "))) {
+ /* didn't find qdisc in output, so we need to add one */
+ g_autoptr(virCommand) addCmd = virCommandNew(TC);
+
+ virCommandAddArgList(addCmd, "qdisc", "add", "dev", ifname, "root",
+ "handle", "1:", "htb", "default",
+ hierarchical_class ? "2" : "1", NULL);
+
+ return virCommandRun(addCmd, NULL);
+ }
+
+ return 0;
}
diff --git a/tests/virnetdevbandwidthtest.c b/tests/virnetdevbandwidthtest.c
index 6d5c847ad7..31aa7f469d 100644
--- a/tests/virnetdevbandwidthtest.c
+++ b/tests/virnetdevbandwidthtest.c
@@ -147,6 +147,7 @@ mymain(void)
"</bandwidth>",
TC " qdisc del dev eth0 root\n"
TC " qdisc del dev eth0 ingress\n"
+ TC " qdisc show dev eth0 handle 1:\n"
TC " qdisc add dev eth0 root handle 1: htb default 1\n"
TC " class add dev eth0 parent 1: classid 1:1 htb rate 1024kbps quantum 87\n"
TC " qdisc add dev eth0 parent 1:1 handle 2: sfq perturb 10\n"
@@ -177,6 +178,7 @@ mymain(void)
"</bandwidth>",
TC " qdisc del dev eth0 root\n"
TC " qdisc del dev eth0 ingress\n"
+ TC " qdisc show dev eth0 handle 1:\n"
TC " qdisc add dev eth0 root handle 1: htb default 1\n"
TC " class add dev eth0 parent 1: classid 1:1 htb rate 1kbps ceil 2kbps burst 4kb quantum 1\n"
TC " qdisc add dev eth0 parent 1:1 handle 2: sfq perturb 10\n"
@@ -199,6 +201,7 @@ mymain(void)
"</bandwidth>",
TC " qdisc del dev eth0 root\n"
TC " qdisc del dev eth0 ingress\n"
+ TC " qdisc show dev eth0 handle 1:\n"
TC " qdisc add dev eth0 root handle 1: htb default 1\n"
TC " class add dev eth0 parent 1: classid 1:1 htb rate 4294967295kbps quantum 366503875\n"
TC " qdisc add dev eth0 parent 1:1 handle 2: sfq perturb 10\n"
--
2.47.1

171
fedora-41/SOURCES/0008-util-add-new-tc-layer-for-virFirewallCmd-objects.patch

@ -1,171 +0,0 @@
From dac9cb9030ac03d18f59884864a0a253e3c9f8f1 Mon Sep 17 00:00:00 2001
From: Laine Stump <laine@redhat.com>
Date: Mon, 25 Nov 2024 22:24:48 -0500
Subject: [PATCH 8/9] util: add new "tc" layer for virFirewallCmd objects
If the layer of a virFirewallCmd is "tc", then the "tc" utility will
be executed using the arguments that had been added to the
virFirewallCmd
tc layer doesn't support auto-rollback command creation (any rollback
needs to be added manually with virFirewallAddRollbackCmd()), and also
tc layer isn't supported by the iptables backend (it would have been
straightforward to add, but the iptables backend doesn't need it, and
I didn't want to take the chance of causing a regression in that
code for no good reason).
Signed-off-by: Laine Stump <laine@redhat.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
src/network/network_nftables.c | 1 +
src/util/virfirewall.c | 66 +++++++++++++++++++++-------------
src/util/virfirewall.h | 1 +
src/util/virfirewalld.c | 1 +
4 files changed, 44 insertions(+), 25 deletions(-)
diff --git a/src/network/network_nftables.c b/src/network/network_nftables.c
index 268d1f12ca..cc184105c3 100644
--- a/src/network/network_nftables.c
+++ b/src/network/network_nftables.c
@@ -73,6 +73,7 @@ VIR_ENUM_IMPL(nftablesLayer,
"",
"ip",
"ip6",
+ "",
);
diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c
index 811b787ecc..9389bcf541 100644
--- a/src/util/virfirewall.c
+++ b/src/util/virfirewall.c
@@ -47,6 +47,7 @@ VIR_ENUM_IMPL(virFirewallLayer,
"ethernet",
"ipv4",
"ipv6",
+ "tc",
);
typedef struct _virFirewallGroup virFirewallGroup;
@@ -57,6 +58,7 @@ VIR_ENUM_IMPL(virFirewallLayerCommand,
EBTABLES,
IPTABLES,
IP6TABLES,
+ TC,
);
struct _virFirewallCmd {
@@ -591,6 +593,7 @@ virFirewallCmdIptablesApply(virFirewall *firewall,
case VIR_FIREWALL_LAYER_IPV6:
virCommandAddArg(cmd, "-w");
break;
+ case VIR_FIREWALL_LAYER_TC:
case VIR_FIREWALL_LAYER_LAST:
break;
}
@@ -672,39 +675,52 @@ virFirewallCmdNftablesApply(virFirewall *firewall G_GNUC_UNUSED,
size_t i;
int status;
- cmd = virCommandNew(NFT);
+ if (fwCmd->layer == VIR_FIREWALL_LAYER_TC) {
- if ((virFirewallTransactionGetFlags(firewall) & VIR_FIREWALL_TRANSACTION_AUTO_ROLLBACK) &&
- fwCmd->argsLen > 1) {
- /* skip any leading options to get to command verb */
- for (i = 0; i < fwCmd->argsLen - 1; i++) {
- if (fwCmd->args[i][0] != '-')
- break;
- }
+ /* for VIR_FIREWALL_LAYER_TC, we run the 'tc' (traffic control) command with
+ * the supplied args.
+ */
+ cmd = virCommandNew(TC);
- if (i + 1 < fwCmd->argsLen &&
- VIR_NFTABLES_ARG_IS_CREATE(fwCmd->args[i])) {
+ /* NB: RAW commands don't support auto-rollback command creation */
- cmdIdx = i;
- objectType = fwCmd->args[i + 1];
+ } else {
- /* we currently only handle auto-rollback for rules,
- * chains, and tables, and those all can be "rolled
- * back" by a delete command using the handle that is
- * returned when "-ae" is added to the add/insert
- * command.
- */
- if (STREQ_NULLABLE(objectType, "rule") ||
- STREQ_NULLABLE(objectType, "chain") ||
- STREQ_NULLABLE(objectType, "table")) {
+ cmd = virCommandNew(NFT);
- needRollback = true;
- /* this option to nft instructs it to add the
- * "handle" of the created object to stdout
+ if ((virFirewallTransactionGetFlags(firewall) & VIR_FIREWALL_TRANSACTION_AUTO_ROLLBACK) &&
+ fwCmd->argsLen > 1) {
+ /* skip any leading options to get to command verb */
+ for (i = 0; i < fwCmd->argsLen - 1; i++) {
+ if (fwCmd->args[i][0] != '-')
+ break;
+ }
+
+ if (i + 1 < fwCmd->argsLen &&
+ VIR_NFTABLES_ARG_IS_CREATE(fwCmd->args[i])) {
+
+ cmdIdx = i;
+ objectType = fwCmd->args[i + 1];
+
+ /* we currently only handle auto-rollback for rules,
+ * chains, and tables, and those all can be "rolled
+ * back" by a delete command using the handle that is
+ * returned when "-ae" is added to the add/insert
+ * command.
*/
- virCommandAddArg(cmd, "-ae");
+ if (STREQ_NULLABLE(objectType, "rule") ||
+ STREQ_NULLABLE(objectType, "chain") ||
+ STREQ_NULLABLE(objectType, "table")) {
+
+ needRollback = true;
+ /* this option to nft instructs it to add the
+ * "handle" of the created object to stdout
+ */
+ virCommandAddArg(cmd, "-ae");
+ }
}
}
+
}
for (i = 0; i < fwCmd->argsLen; i++)
diff --git a/src/util/virfirewall.h b/src/util/virfirewall.h
index bce51259d2..d42e60884b 100644
--- a/src/util/virfirewall.h
+++ b/src/util/virfirewall.h
@@ -39,6 +39,7 @@ typedef enum {
VIR_FIREWALL_LAYER_ETHERNET,
VIR_FIREWALL_LAYER_IPV4,
VIR_FIREWALL_LAYER_IPV6,
+ VIR_FIREWALL_LAYER_TC,
VIR_FIREWALL_LAYER_LAST,
} virFirewallLayer;
diff --git a/src/util/virfirewalld.c b/src/util/virfirewalld.c
index 827e201dbb..124523c420 100644
--- a/src/util/virfirewalld.c
+++ b/src/util/virfirewalld.c
@@ -43,6 +43,7 @@ VIR_LOG_INIT("util.firewalld");
VIR_ENUM_DECL(virFirewallLayerFirewallD);
VIR_ENUM_IMPL(virFirewallLayerFirewallD,
VIR_FIREWALL_LAYER_LAST,
+ "",
"eb",
"ipv4",
"ipv6",
--
2.47.1

687
fedora-41/SOURCES/0009-network-add-tc-filter-rule-to-nftables-backend-to-fi.patch

@ -1,687 +0,0 @@
From b1e2318a0d609fcdff04fcf88953ea87cdd02b95 Mon Sep 17 00:00:00 2001
From: Laine Stump <laine@redhat.com>
Date: Mon, 25 Nov 2024 22:24:49 -0500
Subject: [PATCH 9/9] network: add tc filter rule to nftables backend to fix
checksum of DHCP responses
Please see the commit log for commit v10.9.0-rc1-1-g42ab0148dd for the
history and explanation of the problem that this patch is fixing.
A shorter explanation is that when a guest is connected to a libvirt
virtual network using a virtio-net adapter with in-kernel "vhost-net"
packet processing enabled, it will fail to acquire an IP address from
a DHCP seever running on the host.
In commit v10.9.0-rc1-1-g42ab0148dd we tried fixing this by *zeroing
out* the checksums of these packets with an nftables rule (nftables
can't recompute the checksum, but it can set it to 0) . This
*appeared* to work initially, but it turned out that zeroing the
checksum ends up breaking dhcp packets on *non* virtio/vhost-net guest
interfaces. That attempt was reverted in commit v10.9.0-rc2.
Fortunately, there is an existing way to recompute the checksum of a
packet as it leaves an interface - the "tc" (traffic control) utility
that libvirt already uses for bandwidth management. This patch uses a
tc filter rule to match dhcp response packets on the bridge and
recompute their checksum.
The filter rule must be attached to a tc qdisc, which may also have a
filter attached for bandwidth management (in the <bandwidth> element
of the network config). Not only must we add the qdisc only once
(which was already handled by the patch two prior to this one), but
also the filter rule for checksum fixing and the filter rule for
bandwidth management must be different priorities so they don't clash;
this is solved by adding the checksum-fix filter with "priority 2",
while the bandwidth management filter remains "priority 1" (both will
always be evaluated anyway, it's just a matter of which is evaluated
first).
So far this method has worked with every different guest we could
throw at it, including several that failed with the previous method.
Fixes: b89c4991daa0ee9371f10937fab3b03c5ffdabc6
Reported-by: Rich Jones <rjones@redhat.com>
Reported-by: Andrea Bolognani <abologna@redhat.com>
Fix-Suggested-by: Eric Garver <egarver@redhat.com>
Fix-Suggested-by: Phil Sutter <psutter@redhat.com>
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
src/network/network_nftables.c | 68 +++++++++++++++++++
.../forward-dev-linux.nftables | 40 +++++++++++
.../isolated-linux.nftables | 40 +++++++++++
.../nat-default-linux.nftables | 40 +++++++++++
.../nat-ipv6-linux.nftables | 40 +++++++++++
.../nat-ipv6-masquerade-linux.nftables | 40 +++++++++++
.../nat-many-ips-linux.nftables | 40 +++++++++++
.../nat-no-dhcp-linux.nftables | 40 +++++++++++
.../nat-port-range-ipv6-linux.nftables | 40 +++++++++++
.../nat-port-range-linux.nftables | 40 +++++++++++
.../nat-tftp-linux.nftables | 40 +++++++++++
.../route-default-linux.nftables | 40 +++++++++++
12 files changed, 508 insertions(+)
diff --git a/src/network/network_nftables.c b/src/network/network_nftables.c
index cc184105c3..748edb0273 100644
--- a/src/network/network_nftables.c
+++ b/src/network/network_nftables.c
@@ -29,6 +29,7 @@
#include "internal.h"
#include "virfirewalld.h"
+#include "vircommand.h"
#include "virerror.h"
#include "virlog.h"
#include "virhash.h"
@@ -924,6 +925,67 @@ nftablesAddIPSpecificFirewallRules(virFirewall *fw,
}
+/**
+ * nftablesAddUdpChecksumFixWithTC:
+ *
+ * Add a tc filter rule to @ifname (the bridge device of this network)
+ * that will recompute the checksum of udp packets output from @iface with
+ * destination port @port.
+ *
+ * Normally the checksum should be filled by some part of the basic
+ * network stack, but there are cases (e.g. DHCP response packets sent
+ * from virtualization host to a QEMU guest when the guest NIC uses
+ * vhost-net packet processing) when the host (sender) thinks that
+ * packet checksums will be computed elsewhere (and so leaves a
+ * partially computed checksum in the packet header) while the guest
+ * (receiver) thinks that the checksum has already been fully
+ * computed; in the meantime none of the code in between has actually
+ * finished computing the checksum.
+ *
+ * An example of this is DHCP response packets from host to guest. If
+ * the checksum of each of these packets isn't properly computed, then
+ * many guests (e.g. FreeBSD) will drop them with reason BAD CHECKSUM;
+ * this tc filter rule will fix the ip and udp checksums, and the
+ * FreeBSD dhcp client will happily accept the packet.
+ *
+ * (NB: if you're wondering how the tc qdisc and filter are removed
+ * when the network is destroyed, the answer is that the kernel
+ * automatically (and properly) removes them for us, so we don't need
+ * to worry about keeping track/deleting as we do with nftables rules)
+ */
+static int
+nftablesAddUdpChecksumFixWithTC(virFirewall *fw,
+ const char *iface,
+ int port)
+{
+ g_autofree char *portstr = g_strdup_printf("%d", port);
+
+ /* this will add the qdisc (that the filter below is attached to)
+ * unless it already exists
+ */
+ if (virNetDevBandWidthAddTxFilterParentQdisc(iface, true) < 0)
+ return -1;
+
+ /* add a filter to catch all udp packets with dst "port" and
+ * recompute their checksum
+ */
+ virFirewallAddCmd(fw, VIR_FIREWALL_LAYER_TC,
+ "filter", "add", "dev", iface,
+ "prio", "2", "protocol", "ip", "parent", "1:",
+ "u32", "match", "ip", "dport", portstr, "ffff",
+ "action", "csum", "ip", "and", "udp",
+ NULL);
+
+ virFirewallAddRollbackCmd(fw, VIR_FIREWALL_LAYER_TC,
+ "filter", "del", "dev", iface,
+ "prio", "2", "protocol", "ip", "parent", "1:",
+ "u32", "match", "ip", "dport", portstr, "ffff",
+ "action", "csum", "ip", "and", "udp",
+ NULL);
+ return 0;
+}
+
+
/* nftablesAddFirewallrules:
*
* @def - the network that needs an nftables firewall added
@@ -944,6 +1006,12 @@ nftablesAddFirewallRules(virNetworkDef *def, virFirewall **fwRemoval)
virFirewallStartTransaction(fw, VIR_FIREWALL_TRANSACTION_AUTO_ROLLBACK);
+ /* add the tc filter rule needed to fixup the checksum of dhcp
+ * response packets going from host to guest.
+ */
+ if (nftablesAddUdpChecksumFixWithTC(fw, def->bridge, 68) < 0)
+ return -1;
+
nftablesAddGeneralFirewallRules(fw, def);
for (i = 0;
diff --git a/tests/networkxml2firewalldata/forward-dev-linux.nftables b/tests/networkxml2firewalldata/forward-dev-linux.nftables
index 8badb74beb..6772383b37 100644
--- a/tests/networkxml2firewalldata/forward-dev-linux.nftables
+++ b/tests/networkxml2firewalldata/forward-dev-linux.nftables
@@ -1,3 +1,43 @@
+tc \
+qdisc \
+show \
+dev \
+virbr0 \
+handle \
+1:
+tc \
+qdisc \
+add \
+dev \
+virbr0 \
+root \
+handle \
+1: \
+htb \
+default \
+2
+tc \
+filter \
+add \
+dev \
+virbr0 \
+prio \
+2 \
+protocol \
+ip \
+parent \
+1: \
+u32 \
+match \
+ip \
+dport \
+68 \
+ffff \
+action \
+csum \
+ip \
+and \
+udp
nft \
-ae insert \
rule \
diff --git a/tests/networkxml2firewalldata/isolated-linux.nftables b/tests/networkxml2firewalldata/isolated-linux.nftables
index d1b4dac178..546a18b75a 100644
--- a/tests/networkxml2firewalldata/isolated-linux.nftables
+++ b/tests/networkxml2firewalldata/isolated-linux.nftables
@@ -1,3 +1,43 @@
+tc \
+qdisc \
+show \
+dev \
+virbr0 \
+handle \
+1:
+tc \
+qdisc \
+add \
+dev \
+virbr0 \
+root \
+handle \
+1: \
+htb \
+default \
+2
+tc \
+filter \
+add \
+dev \
+virbr0 \
+prio \
+2 \
+protocol \
+ip \
+parent \
+1: \
+u32 \
+match \
+ip \
+dport \
+68 \
+ffff \
+action \
+csum \
+ip \
+and \
+udp
nft \
-ae insert \
rule \
diff --git a/tests/networkxml2firewalldata/nat-default-linux.nftables b/tests/networkxml2firewalldata/nat-default-linux.nftables
index 28508292f9..08623c1381 100644
--- a/tests/networkxml2firewalldata/nat-default-linux.nftables
+++ b/tests/networkxml2firewalldata/nat-default-linux.nftables
@@ -1,3 +1,43 @@
+tc \
+qdisc \
+show \
+dev \
+virbr0 \
+handle \
+1:
+tc \
+qdisc \
+add \
+dev \
+virbr0 \
+root \
+handle \
+1: \
+htb \
+default \
+2
+tc \
+filter \
+add \
+dev \
+virbr0 \
+prio \
+2 \
+protocol \
+ip \
+parent \
+1: \
+u32 \
+match \
+ip \
+dport \
+68 \
+ffff \
+action \
+csum \
+ip \
+and \
+udp
nft \
-ae insert \
rule \
diff --git a/tests/networkxml2firewalldata/nat-ipv6-linux.nftables b/tests/networkxml2firewalldata/nat-ipv6-linux.nftables
index d8a9ba706d..3fd6b94eef 100644
--- a/tests/networkxml2firewalldata/nat-ipv6-linux.nftables
+++ b/tests/networkxml2firewalldata/nat-ipv6-linux.nftables
@@ -1,3 +1,43 @@
+tc \
+qdisc \
+show \
+dev \
+virbr0 \
+handle \
+1:
+tc \
+qdisc \
+add \
+dev \
+virbr0 \
+root \
+handle \
+1: \
+htb \
+default \
+2
+tc \
+filter \
+add \
+dev \
+virbr0 \
+prio \
+2 \
+protocol \
+ip \
+parent \
+1: \
+u32 \
+match \
+ip \
+dport \
+68 \
+ffff \
+action \
+csum \
+ip \
+and \
+udp
nft \
-ae insert \
rule \
diff --git a/tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.nftables b/tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.nftables
index a7f09cda59..2811e098d1 100644
--- a/tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.nftables
+++ b/tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.nftables
@@ -1,3 +1,43 @@
+tc \
+qdisc \
+show \
+dev \
+virbr0 \
+handle \
+1:
+tc \
+qdisc \
+add \
+dev \
+virbr0 \
+root \
+handle \
+1: \
+htb \
+default \
+2
+tc \
+filter \
+add \
+dev \
+virbr0 \
+prio \
+2 \
+protocol \
+ip \
+parent \
+1: \
+u32 \
+match \
+ip \
+dport \
+68 \
+ffff \
+action \
+csum \
+ip \
+and \
+udp
nft \
-ae insert \
rule \
diff --git a/tests/networkxml2firewalldata/nat-many-ips-linux.nftables b/tests/networkxml2firewalldata/nat-many-ips-linux.nftables
index b826fe6134..5409d5b552 100644
--- a/tests/networkxml2firewalldata/nat-many-ips-linux.nftables
+++ b/tests/networkxml2firewalldata/nat-many-ips-linux.nftables
@@ -1,3 +1,43 @@
+tc \
+qdisc \
+show \
+dev \
+virbr0 \
+handle \
+1:
+tc \
+qdisc \
+add \
+dev \
+virbr0 \
+root \
+handle \
+1: \
+htb \
+default \
+2
+tc \
+filter \
+add \
+dev \
+virbr0 \
+prio \
+2 \
+protocol \
+ip \
+parent \
+1: \
+u32 \
+match \
+ip \
+dport \
+68 \
+ffff \
+action \
+csum \
+ip \
+and \
+udp
nft \
-ae insert \
rule \
diff --git a/tests/networkxml2firewalldata/nat-no-dhcp-linux.nftables b/tests/networkxml2firewalldata/nat-no-dhcp-linux.nftables
index d8a9ba706d..3fd6b94eef 100644
--- a/tests/networkxml2firewalldata/nat-no-dhcp-linux.nftables
+++ b/tests/networkxml2firewalldata/nat-no-dhcp-linux.nftables
@@ -1,3 +1,43 @@
+tc \
+qdisc \
+show \
+dev \
+virbr0 \
+handle \
+1:
+tc \
+qdisc \
+add \
+dev \
+virbr0 \
+root \
+handle \
+1: \
+htb \
+default \
+2
+tc \
+filter \
+add \
+dev \
+virbr0 \
+prio \
+2 \
+protocol \
+ip \
+parent \
+1: \
+u32 \
+match \
+ip \
+dport \
+68 \
+ffff \
+action \
+csum \
+ip \
+and \
+udp
nft \
-ae insert \
rule \
diff --git a/tests/networkxml2firewalldata/nat-port-range-ipv6-linux.nftables b/tests/networkxml2firewalldata/nat-port-range-ipv6-linux.nftables
index ceaed6fa40..d74417cdb3 100644
--- a/tests/networkxml2firewalldata/nat-port-range-ipv6-linux.nftables
+++ b/tests/networkxml2firewalldata/nat-port-range-ipv6-linux.nftables
@@ -1,3 +1,43 @@
+tc \
+qdisc \
+show \
+dev \
+virbr0 \
+handle \
+1:
+tc \
+qdisc \
+add \
+dev \
+virbr0 \
+root \
+handle \
+1: \
+htb \
+default \
+2
+tc \
+filter \
+add \
+dev \
+virbr0 \
+prio \
+2 \
+protocol \
+ip \
+parent \
+1: \
+u32 \
+match \
+ip \
+dport \
+68 \
+ffff \
+action \
+csum \
+ip \
+and \
+udp
nft \
-ae insert \
rule \
diff --git a/tests/networkxml2firewalldata/nat-port-range-linux.nftables b/tests/networkxml2firewalldata/nat-port-range-linux.nftables
index 1dc37a26ec..b55bb287a9 100644
--- a/tests/networkxml2firewalldata/nat-port-range-linux.nftables
+++ b/tests/networkxml2firewalldata/nat-port-range-linux.nftables
@@ -1,3 +1,43 @@
+tc \
+qdisc \
+show \
+dev \
+virbr0 \
+handle \
+1:
+tc \
+qdisc \
+add \
+dev \
+virbr0 \
+root \
+handle \
+1: \
+htb \
+default \
+2
+tc \
+filter \
+add \
+dev \
+virbr0 \
+prio \
+2 \
+protocol \
+ip \
+parent \
+1: \
+u32 \
+match \
+ip \
+dport \
+68 \
+ffff \
+action \
+csum \
+ip \
+and \
+udp
nft \
-ae insert \
rule \
diff --git a/tests/networkxml2firewalldata/nat-tftp-linux.nftables b/tests/networkxml2firewalldata/nat-tftp-linux.nftables
index 28508292f9..08623c1381 100644
--- a/tests/networkxml2firewalldata/nat-tftp-linux.nftables
+++ b/tests/networkxml2firewalldata/nat-tftp-linux.nftables
@@ -1,3 +1,43 @@
+tc \
+qdisc \
+show \
+dev \
+virbr0 \
+handle \
+1:
+tc \
+qdisc \
+add \
+dev \
+virbr0 \
+root \
+handle \
+1: \
+htb \
+default \
+2
+tc \
+filter \
+add \
+dev \
+virbr0 \
+prio \
+2 \
+protocol \
+ip \
+parent \
+1: \
+u32 \
+match \
+ip \
+dport \
+68 \
+ffff \
+action \
+csum \
+ip \
+and \
+udp
nft \
-ae insert \
rule \
diff --git a/tests/networkxml2firewalldata/route-default-linux.nftables b/tests/networkxml2firewalldata/route-default-linux.nftables
index 282c9542a5..76d6902517 100644
--- a/tests/networkxml2firewalldata/route-default-linux.nftables
+++ b/tests/networkxml2firewalldata/route-default-linux.nftables
@@ -1,3 +1,43 @@
+tc \
+qdisc \
+show \
+dev \
+virbr0 \
+handle \
+1:
+tc \
+qdisc \
+add \
+dev \
+virbr0 \
+root \
+handle \
+1: \
+htb \
+default \
+2
+tc \
+filter \
+add \
+dev \
+virbr0 \
+prio \
+2 \
+protocol \
+ip \
+parent \
+1: \
+u32 \
+match \
+ip \
+dport \
+68 \
+ffff \
+action \
+csum \
+ip \
+and \
+udp
nft \
-ae insert \
rule \
--
2.47.1

51
fedora-41/SOURCES/0010-network-permit-forward-mode-open-when-a-network-has-.patch

@ -1,51 +0,0 @@
From 114c0ec656e879ab4d67919914bb24cf5993106d Mon Sep 17 00:00:00 2001
Message-ID: <114c0ec656e879ab4d67919914bb24cf5993106d.1734201785.git.crobinso@redhat.com>
From: Laine Stump <laine@redhat.com>
Date: Mon, 2 Sep 2024 16:13:08 -0400
Subject: [PATCH] network: permit <forward mode='open'/> when a network has no
IP address
Content-type: text/plain
The whole point of <forward mode='open'/> is to supress libvirt from
adding any firewall rules for a network, and someone might want to
create a network with no IP address (i.e. they don't want the guests
to have connectivity to the host via this interface) and no firewall
rules (they don't want any, or they want to add their own). So there's
no reason to fail when a network has <forward mode='open'/> and also
has no IP address.
Kind-of-Resolves: https://gitlab.com/libvirt/libvirt/-/issues/588
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
Signed-off-by: Cole Robinson <crobinso@redhat.com>
---
src/conf/network_conf.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 5cf419acf1..320e1b089a 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -1789,7 +1789,6 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt,
case VIR_NETWORK_FORWARD_ROUTE:
case VIR_NETWORK_FORWARD_NAT:
- case VIR_NETWORK_FORWARD_OPEN:
/* It's pointless to specify L3 forwarding without specifying
* the network we're on.
*/
@@ -1806,8 +1805,10 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt,
def->name);
return NULL;
}
+ break;
- if (def->forward.type == VIR_NETWORK_FORWARD_OPEN && def->forward.nifs) {
+ case VIR_NETWORK_FORWARD_OPEN:
+ if (def->forward.nifs) {
/* an open network by definition can't place any restrictions
* on what traffic is allowed or where it goes, so specifying
* a forwarding device is nonsensical.
--
2.47.1

64
fedora-41/SOURCES/0011-qemu-snapshot-delete-disk-image-only-if-parent-snaps.patch

@ -1,64 +0,0 @@
From d51179fa82448f4720f1645f0b7100df80508cc4 Mon Sep 17 00:00:00 2001
From: Pavel Hrdina <phrdina@redhat.com>
Date: Thu, 9 Jan 2025 16:23:44 +0100
Subject: [PATCH] qemu: snapshot: delete disk image only if parent snapshot is
external
Content-type: text/plain
When we are deleting external snapshot that is not active we only need
to delete overlay disk image of the parent snapshot. This works
correctly even if parent snapshot is external and active as it will have
another overlay created when user reverted to that snapshot.
In case the parent snapshot is internal there are no overlay disk images
created as everything is stored internally within the disk image. In
this case we would delete the actual disk image storing internal
snapshots and most likely the original disk image as well resulting in
data loss once the VM is shutoff.
Fixes: https://gitlab.com/libvirt/libvirt/-/issues/734
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
---
src/qemu/qemu_snapshot.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 18b2e478f6..80cd54bf33 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -3144,6 +3144,8 @@ qemuSnapshotDeleteExternalPrepareData(virDomainObj *vm,
return -1;
}
+ data->parentSnap = qemuSnapshotFindParentSnapForDisk(snap, data->snapDisk);
+
if (data->merge) {
virStorageSource *snapDiskSrc = NULL;
@@ -3185,8 +3187,6 @@ qemuSnapshotDeleteExternalPrepareData(virDomainObj *vm,
qemuSnapshotGetDisksWithBackingStore(vm, snap, data);
}
- data->parentSnap = qemuSnapshotFindParentSnapForDisk(snap, data->snapDisk);
-
if (data->parentSnap && !virDomainSnapshotIsExternal(data->parentSnap)) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("deleting external snapshot that has internal snapshot as parent not supported"));
@@ -3642,10 +3642,12 @@ qemuSnapshotDiscardExternal(virDomainObj *vm,
if (!data->job)
goto error;
} else {
- if (virStorageSourceInit(data->parentDomDisk->src) < 0 ||
- virStorageSourceUnlink(data->parentDomDisk->src) < 0) {
- VIR_WARN("Failed to remove snapshot image '%s'",
- data->snapDisk->name);
+ if (data->parentSnap && virDomainSnapshotIsExternal(data->parentSnap)) {
+ if (virStorageSourceInit(data->parentDomDisk->src) < 0 ||
+ virStorageSourceUnlink(data->parentDomDisk->src) < 0) {
+ VIR_WARN("Failed to remove snapshot image '%s'",
+ data->snapDisk->name);
+ }
}
}
}

3
fedora-41/SOURCES/libvirt-10.6.0.tar.xz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a495b2a26faca841ac0073c7dd7f60857ca81adac9047dac5f698fd75f1342cd
size 9481992

3
fedora-41/SOURCES/zfs-2.3.4.tar.gz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:960dadef24223edf16578de75ab471acdf4119ec8e1402408e8c789577ed305e
size 34377346

3
fedora-41/SOURCES/zfs-2.3.5.tar.gz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:931b78933e365c66ec4695cd0899b31fbe0f4f837fb1bb4144ff2ab19dbada8b
size 34379058

3
fedora-41/SOURCES/zfs-2.4.0.tar.gz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:aacf01a3f75b3a9835321eace7f3c54c7e866c3df04deafa98084cc5541978f9
size 34476233

31
fedora-42/SOURCES/0001-Fix-mocking-of-virQEMUCapsProbeHVF-function.patch

@ -1,31 +0,0 @@
From 5629ebcb4234fde10fd9468d5fc5dd4947ed8677 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Tue, 29 Apr 2025 15:49:10 +0100
Subject: [PATCH] Fix mocking of virQEMUCapsProbeHVF function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
src/qemu/qemu_capabilities.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index ea7c14daa9..488a1a058e 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -943,7 +943,7 @@ bool
virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps) G_NO_INLINE;
bool
-virQEMUCapsProbeHVF(virQEMUCaps *qemuCaps) G_NO_INLINE;
+virQEMUCapsProbeHVF(virQEMUCaps *qemuCaps) G_NO_INLINE __attribute__((noipa));
virArch virQEMUCapsArchFromString(const char *arch);
const char *virQEMUCapsArchToString(virArch arch);
--
2.49.0

85
fedora-42/SOURCES/0001-nss-Skip-empty-files-and-avoid-use-of-uninitialized-.patch

@ -1,85 +0,0 @@
From 63a3d70697dc44ef2f8b40f7c8e9aa869227a7da Mon Sep 17 00:00:00 2001
From: Jiang XueQian <jiangxueqian@gmail.com>
Date: Sat, 18 Jan 2025 16:32:10 +0800
Subject: [PATCH] nss: Skip empty files and avoid use of uninitialized value
Content-type: text/plain
JSON parser isn't called when reading empty files so `jerr` will be used
uninitialized in the original code. Empty files appear when a network
has no dhcp clients.
This patch checks for such files and skip them.
Fixes: a8d828c88bbdaf83ae78dc06cdd84d5667fcc424
Signed-off-by: Jiang XueQian <jiangxueqian@gmail.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
tools/nss/libvirt_nss_leases.c | 9 +++++++--
tools/nss/libvirt_nss_macs.c | 9 +++++++--
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/tools/nss/libvirt_nss_leases.c b/tools/nss/libvirt_nss_leases.c
index aea81bb56e..25ea6b0ce2 100644
--- a/tools/nss/libvirt_nss_leases.c
+++ b/tools/nss/libvirt_nss_leases.c
@@ -263,7 +263,7 @@ findLeases(const char *file,
enum json_tokener_error jerr;
int jsonflags = JSON_TOKENER_STRICT | JSON_TOKENER_VALIDATE_UTF8;
char line[1024];
- ssize_t nreadTotal = 0;
+ size_t nreadTotal = 0;
int rv;
if ((fd = open(file, O_RDONLY)) < 0) {
@@ -290,12 +290,17 @@ findLeases(const char *file,
jerr = json_tokener_get_error(tok);
} while (jerr == json_tokener_continue);
+ if (nreadTotal == 0) {
+ ret = 0;
+ goto cleanup;
+ }
+
if (jerr == json_tokener_continue) {
ERROR("Cannot parse %s: incomplete json found", file);
goto cleanup;
}
- if (nreadTotal > 0 && jerr != json_tokener_success) {
+ if (jerr != json_tokener_success) {
ERROR("Cannot parse %s: %s", file, json_tokener_error_desc(jerr));
goto cleanup;
}
diff --git a/tools/nss/libvirt_nss_macs.c b/tools/nss/libvirt_nss_macs.c
index 23229a18f3..bac8c0e1bb 100644
--- a/tools/nss/libvirt_nss_macs.c
+++ b/tools/nss/libvirt_nss_macs.c
@@ -124,7 +124,7 @@ findMACs(const char *file,
json_tokener *tok = NULL;
enum json_tokener_error jerr;
int jsonflags = JSON_TOKENER_STRICT | JSON_TOKENER_VALIDATE_UTF8;
- ssize_t nreadTotal = 0;
+ size_t nreadTotal = 0;
int rv;
size_t i;
@@ -152,12 +152,17 @@ findMACs(const char *file,
jerr = json_tokener_get_error(tok);
} while (jerr == json_tokener_continue);
+ if (nreadTotal == 0) {
+ ret = 0;
+ goto cleanup;
+ }
+
if (jerr == json_tokener_continue) {
ERROR("Cannot parse %s: incomplete json found", file);
goto cleanup;
}
- if (nreadTotal > 0 && jerr != json_tokener_success) {
+ if (jerr != json_tokener_success) {
ERROR("Cannot parse %s: %s", file, json_tokener_error_desc(jerr));
goto cleanup;
}

68
fedora-42/SOURCES/0001-qemu-Be-more-forgiving-when-acquiring-QUERY-job-when.patch

@ -1,68 +0,0 @@
From cd0de70e05475d5f4aa46e578fbb98033d38c06b Mon Sep 17 00:00:00 2001
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 16 Jun 2025 10:28:37 +0200
Subject: [PATCH] qemu: Be more forgiving when acquiring QUERY job when
formatting domain XML
Content-type: text/plain
In my previous commit of v11.0.0-rc1~115 I've made QEMU driver
implementation for virDomainGetXMLDesc() (qemuDomainGetXMLDesc())
acquire QERY job. See its commit message for more info. But this
unfortunately broke apps witch fetch domain XML for incoming
migration (like virt-manager). The reason is that for incoming
migration the VIR_ASYNC_JOB_MIGRATION_IN async job is set, but
the mask of allowed synchronous jobs is empty (because QEMU can't
talk on monitor really). This makes virDomainObjBeginJob() fail
which in turn makes qemuDomainGetXMLDesc() fail too.
It makes sense for qemuDomainGetXMLDesc() to acquire the job
(e.g. so that it's coherent with another thread that might be in
the middle of a MODIFY job). But failure to dump XML may be
treated as broken daemon (e.g. virt-manager does so).
Therefore, still try to acquire the QUERY job (if job mask
permits it) but, do not treat failure as an error.
Fixes: 6cc93bf28842526be2fd596a607ebca796b7fb2e
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2369243
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
---
src/qemu/qemu_driver.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d2eddbd9ae..6bdeede2e8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6158,6 +6158,7 @@ static char
{
virQEMUDriver *driver = dom->conn->privateData;
virDomainObj *vm;
+ bool hasJob = false;
char *ret = NULL;
virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS | VIR_DOMAIN_XML_UPDATE_CPU,
@@ -6169,8 +6170,10 @@ static char
if (virDomainGetXMLDescEnsureACL(dom->conn, vm->def, flags) < 0)
goto cleanup;
- if (virDomainObjBeginJob(vm, VIR_JOB_QUERY) < 0)
- goto cleanup;
+ if (virDomainNestedJobAllowed(vm->job, VIR_JOB_QUERY) &&
+ virDomainObjBeginJob(vm, VIR_JOB_QUERY) >= 0) {
+ hasJob = true;
+ }
qemuDomainUpdateCurrentMemorySize(vm);
@@ -6186,7 +6189,8 @@ static char
ret = qemuDomainFormatXML(driver, vm, flags);
- virDomainObjEndJob(vm);
+ if (hasJob)
+ virDomainObjEndJob(vm);
cleanup:
virDomainObjEndAPI(&vm);

94
fedora-42/SOURCES/0001-storage-stop-hardcoding-paths-for-mkfs-mount-umount.patch

@ -1,94 +0,0 @@
From 63e4cbd109374f44e8bd4f8d1af5e2a2c67611bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Mon, 28 Apr 2025 11:42:13 +0100
Subject: [PATCH] storage: stop hardcoding paths for mkfs, mount, umount
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Daniel P. Berrangé <berrange@redhat.com>
This was always undesirable but now causes problems on Fedora 42
where at build time we detect a /sbin path but at runtime this
will only exist on upgraded machines, not fresh installs.
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
meson.build | 13 -------------
src/storage/storage_backend_fs.c | 17 +++--------------
2 files changed, 3 insertions(+), 27 deletions(-)
diff --git a/meson.build b/meson.build
index 37b1caa566..14c98b49a1 100644
--- a/meson.build
+++ b/meson.build
@@ -1827,23 +1827,10 @@ if conf.has('WITH_LIBVIRTD')
endif
endif
- if fs_enable
- mount_prog = find_program('mount', required: get_option('storage_fs'), dirs: libvirt_sbin_path)
- umount_prog = find_program('umount', required: get_option('storage_fs'), dirs: libvirt_sbin_path)
- mkfs_prog = find_program('mkfs', required: get_option('storage_fs'), dirs: libvirt_sbin_path)
-
- if not mount_prog.found() or not umount_prog.found() or not mkfs_prog.found()
- fs_enable = false
- endif
- endif
-
if fs_enable
use_storage = true
conf.set('WITH_STORAGE_FS', 1)
- conf.set_quoted('MOUNT', mount_prog.full_path())
- conf.set_quoted('UMOUNT', umount_prog.full_path())
- conf.set_quoted('MKFS', mkfs_prog.full_path())
endif
endif
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index fce395d60f..6ec359625a 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -304,7 +304,7 @@ virStorageBackendFileSystemMount(virStoragePoolObj *pool)
if (!(src = virStorageBackendFileSystemGetPoolSource(pool)))
return -1;
- cmd = virStorageBackendFileSystemMountCmd(MOUNT, def, src);
+ cmd = virStorageBackendFileSystemMountCmd("mount", def, src);
/* Mounting a shared FS might take a long time. Don't hold
* the pool locked meanwhile. */
@@ -362,7 +362,7 @@ virStorageBackendFileSystemStop(virStoragePoolObj *pool)
if ((rc = virStorageBackendFileSystemIsMounted(pool)) != 1)
return rc;
- cmd = virCommandNewArgList(UMOUNT, def->target.path, NULL);
+ cmd = virCommandNewArgList("umount", def->target.path, NULL);
return virCommandRun(cmd, NULL);
}
#endif /* WITH_STORAGE_FS */
@@ -402,18 +402,7 @@ virStorageBackendExecuteMKFS(const char *device,
g_autoptr(virCommand) cmd = NULL;
g_autofree char *mkfs = NULL;
-#if WITH_STORAGE_FS
- mkfs = virFindFileInPath(MKFS);
-#endif /* WITH_STORAGE_FS */
-
- if (!mkfs) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("mkfs is not available on this platform: Failed to make filesystem of type '%1$s' on device '%2$s'"),
- format, device);
- return -1;
- }
-
- cmd = virCommandNewArgList(mkfs, "-t", format, NULL);
+ cmd = virCommandNewArgList("mkfs", "-t", format, NULL);
/* use the force, otherwise mkfs.xfs won't overwrite existing fs.
* Similarly mkfs.ext2, mkfs.ext3, and mkfs.ext4 require supplying -F
--
2.49.0

43
fedora-42/SOURCES/0001-util-avoid-overflow-in-hextable-buffer.patch

@ -1,43 +0,0 @@
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
To: devel@lists.libvirt.org
Subject: [PATCH] util: avoid overflow in hextable buffer
Date: Mon, 20 Jan 2025 10:09:24 +0000
Message-ID: <20250120100924.3864818-1-berrange@redhat.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The assigned string is 17 chars long once the trailing nul is taken
into account. This triggers a warning with GCC 15
src/util/virsystemd.c: In function ‘virSystemdEscapeName’:
src/util/virsystemd.c:59:38: error: initializer-string for array of ‘char’ is too long [-Werror=unterminated-string-initialization]
59 | static const char hextable[16] = "0123456789abcdef";
| ^~~~~~~~~~~~~~~~~~
Switch to a dynamically sized array as used in all the other places
we have a hextable array.
See also: https://gcc.gnu.org/PR115185
Reported-by: Yaakov Selkowitz <yselkowi@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
src/util/virsystemd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
index 5b772e29dd..d46e5f74fc 100644
--- a/src/util/virsystemd.c
+++ b/src/util/virsystemd.c
@@ -56,7 +56,7 @@ struct _virSystemdActivationEntry {
static void virSystemdEscapeName(virBuffer *buf,
const char *name)
{
- static const char hextable[16] = "0123456789abcdef";
+ static const char hextable[] = "0123456789abcdef";
#define ESCAPE(c) \
do { \
--
2.47.1

58
fedora-42/SOURCES/0001-util-stop-hardcoding-numad-path.patch

@ -1,58 +0,0 @@
From 7ab0f1c2a3fddf46d381f055e49111e3063b4829 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Date: Mon, 28 Apr 2025 11:47:34 +0100
Subject: [PATCH] util: stop hardcoding numad path
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
From: Daniel P. Berrangé <berrange@redhat.com>
Change the meson rules to always enable numad if on a Linux host, unless
the meson options say not to.
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
meson.build | 10 +++-------
src/util/virnuma.c | 2 +-
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/meson.build b/meson.build
index 14c98b49a1..767205f44b 100644
--- a/meson.build
+++ b/meson.build
@@ -2028,14 +2028,10 @@ if not get_option('nss').disabled()
endif
endif
-if not get_option('numad').disabled() and numactl_dep.found()
- numad_prog = find_program('numad', required: get_option('numad'), dirs: libvirt_sbin_path)
- if numad_prog.found()
- conf.set('WITH_NUMAD', 1)
- conf.set_quoted('NUMAD', numad_prog.full_path())
- endif
+if not get_option('numad').disabled() and numactl_dep.found() and host_machine.system() == 'linux'
+ conf.set('WITH_NUMAD', 1)
elif get_option('numad').enabled()
- error('You must have numactl enabled for numad support.')
+ error('You must have a Linux host with numactl enabled for numad support.')
endif
# nwfilter should only be compiled for linux, and only if the
diff --git a/src/util/virnuma.c b/src/util/virnuma.c
index 9393c20875..67c51630c7 100644
--- a/src/util/virnuma.c
+++ b/src/util/virnuma.c
@@ -61,7 +61,7 @@ virNumaGetAutoPlacementAdvice(unsigned short vcpus,
g_autoptr(virCommand) cmd = NULL;
char *output = NULL;
- cmd = virCommandNewArgList(NUMAD, "-w", NULL);
+ cmd = virCommandNewArgList("numad", "-w", NULL);
virCommandAddArgFormat(cmd, "%d:%llu", vcpus,
VIR_DIV_UP(balloon, 1024));
--
2.49.0

36
fedora-42/SOURCES/0001-wireshark-Drop-needless-declaration-of-proto_registe.patch

@ -1,36 +0,0 @@
From b825bb556bd3967bf5422c243b77bd4038e317e2 Mon Sep 17 00:00:00 2001
Message-ID: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 13 Oct 2025 10:34:51 +0200
Subject: [PATCH 1/8] wireshark: Drop needless declaration of
proto_register_libvirt() and proto_reg_handoff_libvirt()
Content-type: text/plain
Both proto_register_libvirt() and proto_reg_handoff_libvirt() are
declared in packet-libvirt.h which is included from plugin.c.
There's no need to provide another declaration in plugin.c.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Cole Robinson <crobinso@redhat.com>
---
tools/wireshark/src/plugin.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/tools/wireshark/src/plugin.c b/tools/wireshark/src/plugin.c
index 9a83f2ca07..19b25e7b1a 100644
--- a/tools/wireshark/src/plugin.c
+++ b/tools/wireshark/src/plugin.c
@@ -72,9 +72,6 @@ void plugin_register(void)
#else /* WIRESHARK_VERSION >= 2009000 */
-void proto_register_libvirt(void);
-void proto_reg_handoff_libvirt(void);
-
WS_DLL_PUBLIC_DEF const gchar plugin_version[] = PLUGIN_VERSION;
WS_DLL_PUBLIC_DEF const int plugin_want_major = WIRESHARK_VERSION_MAJOR;
WS_DLL_PUBLIC_DEF const int plugin_want_minor = WIRESHARK_VERSION_MINOR;
--
2.51.0

47
fedora-42/SOURCES/0002-wireshark-Switch-header-files-to-pragma-once.patch

@ -1,47 +0,0 @@
From 41d3b457972bde85991fa7ed6f282370aca4b2af Mon Sep 17 00:00:00 2001
Message-ID: <41d3b457972bde85991fa7ed6f282370aca4b2af.1760476767.git.crobinso@redhat.com>
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Fri, 10 Oct 2025 15:20:05 +0200
Subject: [PATCH 2/8] wireshark: Switch header files to #pragma once
Content-type: text/plain
The genxdrstub.pl script generates some header files. But they
use the old pattern to guard against multiple inclusion:
#ifndef SOMETHING_H
#define SOMETHING_H
...
#endif
Change the script to generate just '#pragma once' used everywhere
else in our code.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Cole Robinson <crobinso@redhat.com>
---
tools/wireshark/util/genxdrstub.pl | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/tools/wireshark/util/genxdrstub.pl b/tools/wireshark/util/genxdrstub.pl
index 8cfda25a27..01b663a88c 100755
--- a/tools/wireshark/util/genxdrstub.pl
+++ b/tools/wireshark/util/genxdrstub.pl
@@ -563,11 +563,8 @@ sub add_header_file {
local $self->{header_contents} = [];
$self->print("/* *DO NOT MODIFY* this file directly.\n");
$self->print(" * This file was generated by $0 from libvirt version $libvirt_version */\n");
- my $ucname = uc $name;
- $self->print("#ifndef _$ucname\_H_\n");
- $self->print("#define _$ucname\_H_\n");
+ $self->print("#pragma once\n");
$block->();
- $self->print("#endif /* _$ucname\_H_ */");
push @{ $self->{headers} }, [ $name, delete $self->{header_contents} ];
}
--
2.51.0

81
fedora-42/SOURCES/0003-wireshark-Move-WIRESHARK_VERSION-macro-definition.patch

@ -1,81 +0,0 @@
From 02a0e78bf54c903da8922c56bade9b3298ade351 Mon Sep 17 00:00:00 2001
Message-ID: <02a0e78bf54c903da8922c56bade9b3298ade351.1760476767.git.crobinso@redhat.com>
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 13 Oct 2025 09:04:17 +0200
Subject: [PATCH 3/8] wireshark: Move WIRESHARK_VERSION macro definition
Content-type: text/plain
Soon, other parts of the wireshark code will need to
differentiate wrt wireshark version. Therefore, move the
WIRESHARK_VERSION macro definition among with its deps into
packet-libvirt.h.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Cole Robinson <crobinso@redhat.com>
---
tools/wireshark/src/packet-libvirt.h | 14 ++++++++++++++
tools/wireshark/src/plugin.c | 14 --------------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/tools/wireshark/src/packet-libvirt.h b/tools/wireshark/src/packet-libvirt.h
index 14e6e13696..15cfcb0534 100644
--- a/tools/wireshark/src/packet-libvirt.h
+++ b/tools/wireshark/src/packet-libvirt.h
@@ -19,5 +19,19 @@
#pragma once
+#ifdef WITH_WS_VERSION
+# include <wireshark/ws_version.h>
+#else
+# include <wireshark/config.h>
+# define WIRESHARK_VERSION_MAJOR VERSION_MAJOR
+# define WIRESHARK_VERSION_MINOR VERSION_MINOR
+# define WIRESHARK_VERSION_MICRO VERSION_MICRO
+#endif
+
+#define WIRESHARK_VERSION \
+ ((WIRESHARK_VERSION_MAJOR * 1000 * 1000) + \
+ (WIRESHARK_VERSION_MINOR * 1000) + \
+ (WIRESHARK_VERSION_MICRO))
+
void proto_register_libvirt(void);
void proto_reg_handoff_libvirt(void);
diff --git a/tools/wireshark/src/plugin.c b/tools/wireshark/src/plugin.c
index 19b25e7b1a..64317b5280 100644
--- a/tools/wireshark/src/plugin.c
+++ b/tools/wireshark/src/plugin.c
@@ -12,15 +12,6 @@
#include <config.h>
-#ifdef WITH_WS_VERSION
-# include <wireshark/ws_version.h>
-#else
-# include <wireshark/config.h>
-# define WIRESHARK_VERSION_MAJOR VERSION_MAJOR
-# define WIRESHARK_VERSION_MINOR VERSION_MINOR
-# define WIRESHARK_VERSION_MICRO VERSION_MICRO
-#endif
-
#define HAVE_PLUGINS 1
#include <wireshark/epan/proto.h>
/* plugins are DLLs */
@@ -32,11 +23,6 @@
/* Let the plugin version be the version of libvirt */
#define PLUGIN_VERSION VERSION
-#define WIRESHARK_VERSION \
- ((WIRESHARK_VERSION_MAJOR * 1000 * 1000) + \
- (WIRESHARK_VERSION_MINOR * 1000) + \
- (WIRESHARK_VERSION_MICRO))
-
#if WIRESHARK_VERSION < 2005000
WS_DLL_PUBLIC_DEF const gchar version[] = VERSION;
--
2.51.0

133
fedora-42/SOURCES/0004-wireshark-Fix-int-type-of-some-virNetMessageHeader-m.patch

@ -1,133 +0,0 @@
From 7374c4ecbd591b02f7be4b2918addc6d5852aafb Mon Sep 17 00:00:00 2001
Message-ID: <7374c4ecbd591b02f7be4b2918addc6d5852aafb.1760476767.git.crobinso@redhat.com>
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Mon, 13 Oct 2025 09:21:30 +0200
Subject: [PATCH 4/8] wireshark: Fix int type of some virNetMessageHeader
members
Content-type: text/plain
Our virNetMessageHeader is a struct that's declared as follows:
struct virNetMessageHeader {
unsigned prog;
unsigned vers;
int proc;
virNetMessageType type;
unsigned serial;
virNetMessageStatus status;
};
Now, per RFC 4506 enums are also encoded as signed integers. This
means, that only 'prog', 'vers' and 'serial' are really unsigned
integers. The others ('proc', 'type' and 'status') are encoded as
signed integers. Fix their type when dissecting.
While at it, also follow latest trend in wireshark and switch
from guint32 to uint32_t.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Cole Robinson <crobinso@redhat.com>
---
tools/wireshark/src/packet-libvirt.c | 34 +++++++++++++++++++---------
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
index da2aabd98a..af14c6bed7 100644
--- a/tools/wireshark/src/packet-libvirt.c
+++ b/tools/wireshark/src/packet-libvirt.c
@@ -92,7 +92,7 @@ typedef gboolean (*vir_xdr_dissector_t)(tvbuff_t *tvb, proto_tree *tree, XDR *xd
typedef struct vir_dissector_index vir_dissector_index_t;
struct vir_dissector_index {
- guint32 proc;
+ int32_t proc;
vir_xdr_dissector_t args;
vir_xdr_dissector_t ret;
vir_xdr_dissector_t msg;
@@ -275,8 +275,10 @@ dissect_xdr_array(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
}
static vir_xdr_dissector_t
-find_payload_dissector(guint32 proc, guint32 type,
- const vir_dissector_index_t *pds, gsize length)
+find_payload_dissector(int32_t proc,
+ enum vir_net_message_type type,
+ const vir_dissector_index_t *pds,
+ gsize length)
{
const vir_dissector_index_t *pd;
guint32 first, last, direction;
@@ -309,6 +311,10 @@ find_payload_dissector(guint32 proc, guint32 type,
return pd->ret;
case VIR_NET_MESSAGE:
return pd->msg;
+ case VIR_NET_STREAM:
+ case VIR_NET_STREAM_HOLE:
+ /* Handled elsewhere */
+ return NULL;
}
return NULL;
}
@@ -397,8 +403,12 @@ dissect_xdr_stream_hole(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
#include "libvirt/protocol.h"
static void
-dissect_libvirt_payload(tvbuff_t *tvb, proto_tree *tree,
- guint32 prog, guint32 proc, guint32 type, guint32 status)
+dissect_libvirt_payload(tvbuff_t *tvb,
+ proto_tree *tree,
+ uint32_t prog,
+ int32_t proc,
+ int32_t type,
+ int32_t status)
{
gssize payload_length;
@@ -430,7 +440,8 @@ dissect_libvirt_payload(tvbuff_t *tvb, proto_tree *tree,
return;
unknown:
- dbg("Cannot determine payload: Prog=%u, Proc=%u, Type=%u, Status=%u", prog, proc, type, status);
+ dbg("Cannot determine payload: Prog=%u, Proc=%d, Type=%d, Status=%d",
+ prog, proc, type, status);
proto_tree_add_item(tree, hf_libvirt_unknown, tvb, VIR_HEADER_LEN, -1, ENC_NA);
}
@@ -439,7 +450,8 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
void *opaque G_GNUC_UNUSED)
{
goffset offset;
- guint32 prog, proc, type, serial, status;
+ uint32_t prog, serial;
+ int32_t proc, type, status;
const value_string *vs;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Libvirt");
@@ -448,17 +460,17 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
offset = 4; /* End of length field */
prog = tvb_get_ntohl(tvb, offset); offset += 4;
offset += 4; /* Ignore version header field */
- proc = tvb_get_ntohl(tvb, offset); offset += 4;
- type = tvb_get_ntohl(tvb, offset); offset += 4;
+ proc = tvb_get_ntohil(tvb, offset); offset += 4;
+ type = tvb_get_ntohil(tvb, offset); offset += 4;
serial = tvb_get_ntohl(tvb, offset); offset += 4;
- status = tvb_get_ntohl(tvb, offset); offset += 4;
+ status = tvb_get_ntohil(tvb, offset); offset += 4;
col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s",
val_to_str(prog, program_strings, "%x"));
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS);
if (vs == NULL) {
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%u", proc);
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%d", proc);
} else {
col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", val_to_str(proc, vs, "%d"));
}
--
2.51.0

46
fedora-42/SOURCES/0005-wireshark-Don-t-special-case-retval-of-get_program_d.patch

@ -1,46 +0,0 @@
From 1086888f95a322101f8cf53b63c96600ccbeb882 Mon Sep 17 00:00:00 2001
Message-ID: <1086888f95a322101f8cf53b63c96600ccbeb882.1760476767.git.crobinso@redhat.com>
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Fri, 10 Oct 2025 19:16:54 +0200
Subject: [PATCH 5/8] wireshark: Don't special case retval of
get_program_data() in dissect_libvirt_message()
Content-type: text/plain
The get_program_data() function returns a pointer (in this
specific case to an array of procedure strings) which, if
non-NULL is then passed val_to_str(). Well, if val_to_str() sees
NULL it is treated gracefully, i.e. like if the numeric value
'proc' wasn't found in the array.
Therefore, there's no need to special case call to
col_append_fstr(). Both result into the same behaviour.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Cole Robinson <crobinso@redhat.com>
---
tools/wireshark/src/packet-libvirt.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
index af14c6bed7..6c729801d4 100644
--- a/tools/wireshark/src/packet-libvirt.c
+++ b/tools/wireshark/src/packet-libvirt.c
@@ -469,11 +469,7 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
val_to_str(prog, program_strings, "%x"));
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS);
- if (vs == NULL) {
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%d", proc);
- } else {
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", val_to_str(proc, vs, "%d"));
- }
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", val_to_str(proc, vs, "%d"));
col_append_fstr(pinfo->cinfo, COL_INFO, " Type=%s Serial=%u Status=%s",
val_to_str(type, type_strings, "%d"), serial,
--
2.51.0

68
fedora-42/SOURCES/0006-wireshark-Introduce-and-use-vir_val_to_str.patch

@ -1,68 +0,0 @@
From ba2c4bdd5cbccd5c0673149cf76802c98b70d2f7 Mon Sep 17 00:00:00 2001
Message-ID: <ba2c4bdd5cbccd5c0673149cf76802c98b70d2f7.1760476767.git.crobinso@redhat.com>
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Fri, 10 Oct 2025 18:23:18 +0200
Subject: [PATCH 6/8] wireshark: Introduce and use vir_val_to_str()
Content-type: text/plain
Wireshark offers val_to_str() function which converts numeric
value to string by looking up value ('val') in an array ('vs') of
<val, string> pairs. If no corresponding string is found, then
the value is formatted using given 'fmt' string.
Starting from wireshark-4.6.0 not only this function gained
another argument but also returns a strdup()-ed string. To keep
our code simple, let's introduce a wrapper so which can be then
adjusted as needed.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Cole Robinson <crobinso@redhat.com>
---
tools/wireshark/src/packet-libvirt.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
index 6c729801d4..f6ad2c4578 100644
--- a/tools/wireshark/src/packet-libvirt.c
+++ b/tools/wireshark/src/packet-libvirt.c
@@ -140,6 +140,15 @@ static const value_string status_strings[] = {
{ -1, NULL }
};
+static const char *
+G_GNUC_PRINTF(3, 0)
+vir_val_to_str(const uint32_t val,
+ const value_string *vs,
+ const char *fmt)
+{
+ return val_to_str(val, vs, fmt);
+}
+
static gboolean
dissect_xdr_string(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
guint32 maxlen)
@@ -466,14 +475,14 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
status = tvb_get_ntohil(tvb, offset); offset += 4;
col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s",
- val_to_str(prog, program_strings, "%x"));
+ vir_val_to_str(prog, program_strings, "%x"));
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS);
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", val_to_str(proc, vs, "%d"));
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", vir_val_to_str(proc, vs, "%d"));
col_append_fstr(pinfo->cinfo, COL_INFO, " Type=%s Serial=%u Status=%s",
- val_to_str(type, type_strings, "%d"), serial,
- val_to_str(status, status_strings, "%d"));
+ vir_val_to_str(type, type_strings, "%d"), serial,
+ vir_val_to_str(status, status_strings, "%d"));
if (tree) {
gint *hf_proc;
--
2.51.0

165
fedora-42/SOURCES/0007-wireshark-Don-t-leak-column-strings.patch

@ -1,165 +0,0 @@
From 002b9f559d69b92e77ab2d234df6966fecdaf0ec Mon Sep 17 00:00:00 2001
Message-ID: <002b9f559d69b92e77ab2d234df6966fecdaf0ec.1760476767.git.crobinso@redhat.com>
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Fri, 10 Oct 2025 19:13:48 +0200
Subject: [PATCH 7/8] wireshark: Don't leak column strings
Content-type: text/plain
One of the problems of using val_to_str() is that it may return a
const string from given table ('vs'), OR return an allocated one.
Since the caller has no idea which case it is, it resides to safe
option and don't free returned string. But that might lead to a
memleak. This behaviour is fixed with wireshark-4.6.0 and support
for it will be introduced soon. But first, make vir_val_to_str()
behave like fixed val_to_str() from newer wireshark: just always
allocate the string.
Now, if val_to_str() needs to allocate new memory it obtains
allocator by calling wmem_packet_scope() which is what we may do
too.
Hand in hand with that, we need to free the memory using the
correct allocator, hence wmem_free(). But let's put it into a
wrapper vir_wmem_free() because just like val_to_str(), it'll
need additional argument when adapting to new wireshark.
Oh, and freeing the memory right after col_add_fstr() is safe as
it uses vsnprintf() under the hood to format passed args.
One last thing, the wmem.h file used to live under epan/wmem/ but
then in v3.5.0~240 [1] was moved to wsutil/wmem/.
1: https://gitlab.com/wireshark/wireshark/-/commit/7f9c1f5f92c131354fc8b2b88d473706786064c0
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Cole Robinson <crobinso@redhat.com>
---
meson.build | 20 ++++++++++++++++
tools/wireshark/src/meson.build | 1 +
tools/wireshark/src/packet-libvirt.c | 35 ++++++++++++++++++++++------
3 files changed, 49 insertions(+), 7 deletions(-)
diff --git a/meson.build b/meson.build
index bcc18b20e5..a1e0e5ecd5 100644
--- a/meson.build
+++ b/meson.build
@@ -1365,6 +1365,26 @@ if wireshark_dep.found()
if cc.check_header('wireshark/ws_version.h')
conf.set('WITH_WS_VERSION', 1)
endif
+
+ # Find wmem.h
+ # But it's not as easy as you'd think. Ubuntu 20.04 has split parts of
+ # libwireshark.so into libwsutil.so but:
+ # a) wireshark.pc never mentions it,
+ # b) libwsutil-dev package doesn't install pkg-config file.
+ # Fortunately, it's fixed in 24.04.
+ if cc.check_header('wireshark/epan/wmem/wmem.h', dependencies: wireshark_dep)
+ conf.set('WITH_WS_EPAN_WMEM', 1)
+ elif cc.check_header('wireshark/wsutil/wmem/wmem.h', dependencies: wireshark_dep)
+ conf.set('WITH_WS_WSUTIL_WMEM', 1)
+ else
+ error('Unable to locate wmem.h file')
+ endif
+
+ # TODO: drop wsutil dep once support for Ubuntu 20.04 is dropped
+ wsutil_dep = dependency('', required: false)
+ if not cc.has_function('wmem_free', dependencies: wireshark_dep)
+ wsutil_dep = cc.find_library('wsutil', required: true)
+ endif
endif
# generic build dependencies checks
diff --git a/tools/wireshark/src/meson.build b/tools/wireshark/src/meson.build
index 9b452dc5ca..ba0df913e0 100644
--- a/tools/wireshark/src/meson.build
+++ b/tools/wireshark/src/meson.build
@@ -9,6 +9,7 @@ shared_library(
],
dependencies: [
wireshark_dep,
+ wsutil_dep,
xdr_dep,
tools_dep,
],
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
index f6ad2c4578..3178ac6f27 100644
--- a/tools/wireshark/src/packet-libvirt.c
+++ b/tools/wireshark/src/packet-libvirt.c
@@ -21,6 +21,11 @@
#include <wireshark/epan/proto.h>
#include <wireshark/epan/packet.h>
#include <wireshark/epan/dissectors/packet-tcp.h>
+#ifdef WITH_WS_EPAN_WMEM
+# include <wireshark/epan/wmem/wmem.h>
+#elif WITH_WS_WSUTIL_WMEM
+# include <wireshark/wsutil/wmem/wmem.h>
+#endif
#include <rpc/types.h>
#include <rpc/xdr.h>
#include "packet-libvirt.h"
@@ -140,13 +145,19 @@ static const value_string status_strings[] = {
{ -1, NULL }
};
-static const char *
+static char *
G_GNUC_PRINTF(3, 0)
vir_val_to_str(const uint32_t val,
const value_string *vs,
const char *fmt)
{
- return val_to_str(val, vs, fmt);
+ return val_to_str_wmem(wmem_packet_scope(), val, vs, fmt);
+}
+
+static void
+vir_wmem_free(void *ptr)
+{
+ wmem_free(wmem_packet_scope(), ptr);
}
static gboolean
@@ -462,6 +473,10 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
uint32_t prog, serial;
int32_t proc, type, status;
const value_string *vs;
+ char *prog_str = NULL;
+ char *proc_str = NULL;
+ char *type_str = NULL;
+ char *status_str = NULL;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Libvirt");
col_clear(pinfo->cinfo, COL_INFO);
@@ -474,15 +489,21 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
serial = tvb_get_ntohl(tvb, offset); offset += 4;
status = tvb_get_ntohil(tvb, offset); offset += 4;
- col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s",
- vir_val_to_str(prog, program_strings, "%x"));
+ prog_str = vir_val_to_str(prog, program_strings, "%x");
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s", prog_str);
+ vir_wmem_free(prog_str);
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS);
- col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", vir_val_to_str(proc, vs, "%d"));
+ proc_str = vir_val_to_str(proc, vs, "%d");
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", proc_str);
+ vir_wmem_free(proc_str);
+ type_str = vir_val_to_str(type, type_strings, "%d");
+ status_str = vir_val_to_str(status, status_strings, "%d");
col_append_fstr(pinfo->cinfo, COL_INFO, " Type=%s Serial=%u Status=%s",
- vir_val_to_str(type, type_strings, "%d"), serial,
- vir_val_to_str(status, status_strings, "%d"));
+ type_str, serial, status_str);
+ vir_wmem_free(status_str);
+ vir_wmem_free(type_str);
if (tree) {
gint *hf_proc;
--
2.51.0

493
fedora-42/SOURCES/0008-wireshark-Adapt-to-wireshark-4.6.0.patch

@ -1,493 +0,0 @@
From b42a12174c787b99cd6fcb29b44e4b13bd64ee58 Mon Sep 17 00:00:00 2001
Message-ID: <b42a12174c787b99cd6fcb29b44e4b13bd64ee58.1760476767.git.crobinso@redhat.com>
In-Reply-To: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
References: <b825bb556bd3967bf5422c243b77bd4038e317e2.1760476767.git.crobinso@redhat.com>
From: Michal Privoznik <mprivozn@redhat.com>
Date: Fri, 10 Oct 2025 15:22:34 +0200
Subject: [PATCH 8/8] wireshark: Adapt to wireshark-4.6.0
Content-type: text/plain
The main difference is that wmem_packet_scope() is gone [1] but
the packet_info struct has 'pool` member which points to the
allocator used for given packet.
Unfortunately, while we were given pointer to packet_info at the
entry level to our dissector (dissect_libvirt() ->
tcp_dissect_pdus() -> dissect_libvirt_message()) it was never
propagated to generated/primitive dissectors.
But not all dissectors need to allocate memory, so mark the new
argument as unused. And while our generator could be rewritten so
that the argument is annotated as unused iff it's really unused,
I couldn't bother rewriting it. It's generated code after all.
Too much work for little gain.
Another significant change is that val_to_str() now requires new
argument: pointer to allocator to use because it always allocates
new memory [2][3].
1: https://gitlab.com/wireshark/wireshark/-/commit/5ca5c9ca372e06881b23ba9f4fdcb6b479886444
2: https://gitlab.com/wireshark/wireshark/-/commit/b63599762468e4cf1783419a5556377604d344bb
3: https://gitlab.com/wireshark/wireshark/-/commit/84799be215313e61b83a3eaf074f89d6ee349b8c
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/823
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: Cole Robinson <crobinso@redhat.com>
---
tools/wireshark/src/packet-libvirt.c | 157 +++++++++++++++++++--------
tools/wireshark/util/genxdrstub.pl | 18 +--
2 files changed, 119 insertions(+), 56 deletions(-)
diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c
index 3178ac6f27..c5c8fb4756 100644
--- a/tools/wireshark/src/packet-libvirt.c
+++ b/tools/wireshark/src/packet-libvirt.c
@@ -63,7 +63,7 @@ static gint ett_libvirt_stream_hole = -1;
#define XDR_PRIMITIVE_DISSECTOR(xtype, ctype, ftype) \
static gboolean \
- dissect_xdr_##xtype(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf) \
+ dissect_xdr_##xtype(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf) \
{ \
goffset start; \
ctype val; \
@@ -93,7 +93,7 @@ XDR_PRIMITIVE_DISSECTOR(bool, bool_t, boolean)
VIR_WARNINGS_RESET
-typedef gboolean (*vir_xdr_dissector_t)(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf);
+typedef gboolean (*vir_xdr_dissector_t)(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, XDR *xdrs, int hf);
typedef struct vir_dissector_index vir_dissector_index_t;
struct vir_dissector_index {
@@ -146,22 +146,32 @@ static const value_string status_strings[] = {
};
static char *
-G_GNUC_PRINTF(3, 0)
-vir_val_to_str(const uint32_t val,
+G_GNUC_PRINTF(4, 0)
+vir_val_to_str(packet_info *pinfo,
+ const uint32_t val,
const value_string *vs,
const char *fmt)
{
- return val_to_str_wmem(wmem_packet_scope(), val, vs, fmt);
+#if WIRESHARK_VERSION < 4006000
+ return val_to_str_wmem(pinfo->pool, val, vs, fmt);
+#else
+ return val_to_str(pinfo->pool, val, vs, fmt);
+#endif
}
static void
-vir_wmem_free(void *ptr)
+vir_wmem_free(packet_info *pinfo,
+ void *ptr)
{
- wmem_free(wmem_packet_scope(), ptr);
+ wmem_free(pinfo->pool, ptr);
}
static gboolean
-dissect_xdr_string(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
+dissect_xdr_string(tvbuff_t *tvb,
+ packet_info *pinfo G_GNUC_UNUSED,
+ proto_tree *tree,
+ XDR *xdrs,
+ int hf,
guint32 maxlen)
{
goffset start;
@@ -179,7 +189,11 @@ dissect_xdr_string(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
}
static gboolean
-dissect_xdr_opaque(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
+dissect_xdr_opaque(tvbuff_t *tvb,
+ packet_info *pinfo,
+ proto_tree *tree,
+ XDR *xdrs,
+ int hf,
guint32 size)
{
goffset start;
@@ -190,7 +204,7 @@ dissect_xdr_opaque(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
start = xdr_getpos(xdrs);
if ((rc = xdr_opaque(xdrs, (caddr_t)val, size))) {
gint len = xdr_getpos(xdrs) - start;
- const char *s = tvb_bytes_to_str(wmem_packet_scope(), tvb, start, len);
+ const char *s = tvb_bytes_to_str(pinfo->pool, tvb, start, len);
proto_tree_add_bytes_format_value(tree, hf, tvb, start, len, NULL, "%s", s);
} else {
@@ -202,7 +216,11 @@ dissect_xdr_opaque(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
}
static gboolean
-dissect_xdr_bytes(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
+dissect_xdr_bytes(tvbuff_t *tvb,
+ packet_info *pinfo,
+ proto_tree *tree,
+ XDR *xdrs,
+ int hf,
guint32 maxlen)
{
goffset start;
@@ -212,7 +230,7 @@ dissect_xdr_bytes(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
start = xdr_getpos(xdrs);
if (xdr_bytes(xdrs, (char **)&val, &length, maxlen)) {
gint len = xdr_getpos(xdrs) - start;
- const char *s = tvb_bytes_to_str(wmem_packet_scope(), tvb, start, len);
+ const char *s = tvb_bytes_to_str(pinfo->pool, tvb, start, len);
proto_tree_add_bytes_format_value(tree, hf, tvb, start, len, NULL, "%s", s);
free(val);
@@ -224,7 +242,11 @@ dissect_xdr_bytes(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
}
static gboolean
-dissect_xdr_pointer(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
+dissect_xdr_pointer(tvbuff_t *tvb,
+ packet_info *pinfo,
+ proto_tree *tree,
+ XDR *xdrs,
+ int hf,
vir_xdr_dissector_t dissect)
{
goffset start;
@@ -236,7 +258,7 @@ dissect_xdr_pointer(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
return FALSE;
}
if (not_null) {
- return dissect(tvb, tree, xdrs, hf);
+ return dissect(tvb, pinfo, tree, xdrs, hf);
} else {
proto_item *ti;
ti = proto_tree_add_item(tree, hf, tvb, start, xdr_getpos(xdrs) - start, ENC_NA);
@@ -246,15 +268,22 @@ dissect_xdr_pointer(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf,
}
static gboolean
-dissect_xdr_iterable(tvbuff_t *tvb, proto_item *ti, XDR *xdrs, gint ett, int rhf,
- guint32 length, vir_xdr_dissector_t dissect, goffset start)
+dissect_xdr_iterable(tvbuff_t *tvb,
+ packet_info *pinfo,
+ proto_item *ti,
+ XDR *xdrs,
+ gint ett,
+ int rhf,
+ guint32 length,
+ vir_xdr_dissector_t dissect,
+ goffset start)
{
proto_tree *tree;
guint32 i;
tree = proto_item_add_subtree(ti, ett);
for (i = 0; i < length; i++) {
- if (!dissect(tvb, tree, xdrs, rhf))
+ if (!dissect(tvb, pinfo, tree, xdrs, rhf))
return FALSE;
}
proto_item_set_len(ti, xdr_getpos(xdrs) - start);
@@ -262,8 +291,16 @@ dissect_xdr_iterable(tvbuff_t *tvb, proto_item *ti, XDR *xdrs, gint ett, int rhf
}
static gboolean
-dissect_xdr_vector(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
- int rhf, const gchar *rtype, guint32 size, vir_xdr_dissector_t dissect)
+dissect_xdr_vector(tvbuff_t *tvb,
+ packet_info *pinfo,
+ proto_tree *tree,
+ XDR *xdrs,
+ int hf,
+ gint ett,
+ int rhf,
+ const gchar *rtype,
+ guint32 size,
+ vir_xdr_dissector_t dissect)
{
goffset start;
proto_item *ti;
@@ -271,12 +308,20 @@ dissect_xdr_vector(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
start = xdr_getpos(xdrs);
ti = proto_tree_add_item(tree, hf, tvb, start, -1, ENC_NA);
proto_item_append_text(ti, " :: %s[%u]", rtype, size);
- return dissect_xdr_iterable(tvb, ti, xdrs, ett, rhf, size, dissect, start);
+ return dissect_xdr_iterable(tvb, pinfo, ti, xdrs, ett, rhf, size, dissect, start);
}
static gboolean
-dissect_xdr_array(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
- int rhf, const gchar *rtype, guint32 maxlen, vir_xdr_dissector_t dissect)
+dissect_xdr_array(tvbuff_t *tvb,
+ packet_info *pinfo,
+ proto_tree *tree,
+ XDR *xdrs,
+ int hf,
+ gint ett,
+ int rhf,
+ const gchar *rtype,
+ guint32 maxlen,
+ vir_xdr_dissector_t dissect)
{
goffset start;
proto_item *ti;
@@ -291,7 +336,7 @@ dissect_xdr_array(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett,
ti = proto_tree_add_item(tree, hf, tvb, start, -1, ENC_NA);
proto_item_append_text(ti, " :: %s<%u>", rtype, length);
- return dissect_xdr_iterable(tvb, ti, xdrs, ett, rhf, length, dissect, start);
+ return dissect_xdr_iterable(tvb, pinfo, ti, xdrs, ett, rhf, length, dissect, start);
}
static vir_xdr_dissector_t
@@ -340,7 +385,10 @@ find_payload_dissector(int32_t proc,
}
static void
-dissect_libvirt_stream(tvbuff_t *tvb, proto_tree *tree, gint payload_length)
+dissect_libvirt_stream(tvbuff_t *tvb,
+ packet_info *pinfo G_GNUC_UNUSED,
+ proto_tree *tree,
+ gint payload_length)
{
proto_tree_add_item(tree, hf_libvirt_stream, tvb, VIR_HEADER_LEN,
payload_length - VIR_HEADER_LEN, ENC_NA);
@@ -357,6 +405,7 @@ dissect_libvirt_num_of_fds(tvbuff_t *tvb, proto_tree *tree)
static void
dissect_libvirt_fds(tvbuff_t *tvb G_GNUC_UNUSED,
+ packet_info *pinfo G_GNUC_UNUSED,
gint start G_GNUC_UNUSED,
gint32 nfds G_GNUC_UNUSED)
{
@@ -364,8 +413,12 @@ dissect_libvirt_fds(tvbuff_t *tvb G_GNUC_UNUSED,
}
static void
-dissect_libvirt_payload_xdr_data(tvbuff_t *tvb, proto_tree *tree, gint payload_length,
- gint32 status, vir_xdr_dissector_t dissect)
+dissect_libvirt_payload_xdr_data(tvbuff_t *tvb,
+ packet_info *pinfo,
+ proto_tree *tree,
+ gint payload_length,
+ gint32 status,
+ vir_xdr_dissector_t dissect)
{
gint32 nfds = 0;
gint start = VIR_HEADER_LEN;
@@ -384,17 +437,21 @@ dissect_libvirt_payload_xdr_data(tvbuff_t *tvb, proto_tree *tree, gint payload_l
payload_data = (caddr_t)tvb_memdup(NULL, payload_tvb, 0, payload_length);
xdrmem_create(&xdrs, payload_data, payload_length, XDR_DECODE);
- dissect(payload_tvb, tree, &xdrs, -1);
+ dissect(payload_tvb, pinfo, tree, &xdrs, -1);
xdr_destroy(&xdrs);
g_free(payload_data);
if (nfds != 0)
- dissect_libvirt_fds(tvb, start + payload_length, nfds);
+ dissect_libvirt_fds(tvb, pinfo, start + payload_length, nfds);
}
static gboolean
-dissect_xdr_stream_hole(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
+dissect_xdr_stream_hole(tvbuff_t *tvb,
+ packet_info *pinfo,
+ proto_tree *tree,
+ XDR *xdrs,
+ int hf)
{
goffset start;
proto_item *ti;
@@ -411,10 +468,10 @@ dissect_xdr_stream_hole(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
tree = proto_item_add_subtree(ti, ett_libvirt_stream_hole);
hf = hf_libvirt_stream_hole_length;
- if (!dissect_xdr_hyper(tvb, tree, xdrs, hf)) return FALSE;
+ if (!dissect_xdr_hyper(tvb, pinfo, tree, xdrs, hf)) return FALSE;
hf = hf_libvirt_stream_hole_flags;
- if (!dissect_xdr_u_int(tvb, tree, xdrs, hf)) return FALSE;
+ if (!dissect_xdr_u_int(tvb, pinfo, tree, xdrs, hf)) return FALSE;
proto_item_set_len(ti, xdr_getpos(xdrs) - start);
return TRUE;
@@ -424,6 +481,7 @@ dissect_xdr_stream_hole(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
static void
dissect_libvirt_payload(tvbuff_t *tvb,
+ packet_info *pinfo,
proto_tree *tree,
uint32_t prog,
int32_t proc,
@@ -447,13 +505,13 @@ dissect_libvirt_payload(tvbuff_t *tvb,
xd = find_payload_dissector(proc, type, pds, *len);
if (xd == NULL)
goto unknown;
- dissect_libvirt_payload_xdr_data(tvb, tree, payload_length, status, xd);
+ dissect_libvirt_payload_xdr_data(tvb, pinfo, tree, payload_length, status, xd);
} else if (status == VIR_NET_ERROR) {
- dissect_libvirt_payload_xdr_data(tvb, tree, payload_length, status, dissect_xdr_remote_error);
+ dissect_libvirt_payload_xdr_data(tvb, pinfo, tree, payload_length, status, dissect_xdr_remote_error);
} else if (type == VIR_NET_STREAM) { /* implicitly, status == VIR_NET_CONTINUE */
- dissect_libvirt_stream(tvb, tree, payload_length);
+ dissect_libvirt_stream(tvb, pinfo, tree, payload_length);
} else if (type == VIR_NET_STREAM_HOLE) {
- dissect_libvirt_payload_xdr_data(tvb, tree, payload_length, status, dissect_xdr_stream_hole);
+ dissect_libvirt_payload_xdr_data(tvb, pinfo, tree, payload_length, status, dissect_xdr_stream_hole);
} else {
goto unknown;
}
@@ -489,21 +547,21 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
serial = tvb_get_ntohl(tvb, offset); offset += 4;
status = tvb_get_ntohil(tvb, offset); offset += 4;
- prog_str = vir_val_to_str(prog, program_strings, "%x");
+ prog_str = vir_val_to_str(pinfo, prog, program_strings, "%x");
col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s", prog_str);
- vir_wmem_free(prog_str);
+ vir_wmem_free(pinfo, prog_str);
vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS);
- proc_str = vir_val_to_str(proc, vs, "%d");
+ proc_str = vir_val_to_str(pinfo, proc, vs, "%d");
col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s", proc_str);
- vir_wmem_free(proc_str);
+ vir_wmem_free(pinfo, proc_str);
- type_str = vir_val_to_str(type, type_strings, "%d");
- status_str = vir_val_to_str(status, status_strings, "%d");
+ type_str = vir_val_to_str(pinfo, type, type_strings, "%d");
+ status_str = vir_val_to_str(pinfo, status, status_strings, "%d");
col_append_fstr(pinfo->cinfo, COL_INFO, " Type=%s Serial=%u Status=%s",
type_str, serial, status_str);
- vir_wmem_free(status_str);
- vir_wmem_free(type_str);
+ vir_wmem_free(pinfo, status_str);
+ vir_wmem_free(pinfo, type_str);
if (tree) {
gint *hf_proc;
@@ -532,21 +590,26 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_tree_add_item(libvirt_tree, hf_libvirt_status, tvb, offset, 4, ENC_NA); offset += 4;
/* Dissect payload remaining */
- dissect_libvirt_payload(tvb, libvirt_tree, prog, proc, type, status);
+ dissect_libvirt_payload(tvb, pinfo, libvirt_tree, prog, proc, type, status);
}
return 0;
}
static guint
-get_message_len(packet_info *pinfo G_GNUC_UNUSED, tvbuff_t *tvb, int offset, void *data G_GNUC_UNUSED)
+get_message_len(packet_info *pinfo G_GNUC_UNUSED,
+ tvbuff_t *tvb,
+ int offset,
+ void *data G_GNUC_UNUSED)
{
return tvb_get_ntohl(tvb, offset);
}
static int
-dissect_libvirt(tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree, void *data G_GNUC_UNUSED)
+dissect_libvirt(tvbuff_t *tvb,
+ packet_info *pinfo,
+ proto_tree *tree,
+ void *data G_GNUC_UNUSED)
{
/* Another magic const - 4; simply, how much bytes
* is needed to tell the length of libvirt packet. */
diff --git a/tools/wireshark/util/genxdrstub.pl b/tools/wireshark/util/genxdrstub.pl
index 01b663a88c..f69695c091 100755
--- a/tools/wireshark/util/genxdrstub.pl
+++ b/tools/wireshark/util/genxdrstub.pl
@@ -250,7 +250,7 @@ sub xdr_type {
sub render_caller {
my ($self, $hfid) = @_;
my $name = $c->rinc( 'dissect_xdr_'.($self->idstrip || lc($self->xdr_type)) );
- "$name(tvb, tree, xdrs, hf)";
+ "$name(tvb, pinfo, tree, xdrs, hf)";
}
sub ft_type {
@@ -345,7 +345,7 @@ BEGIN{::register_profile(
sub render_caller {
my ($self) = @_;
my ($klass) = ref($self) =~ /([^:]+)$/;
- sprintf '%s(tvb, tree, xdrs, hf, %s)',
+ sprintf '%s(tvb, pinfo, tree, xdrs, hf, %s)',
$c->rinc('dissect_xdr_'.lc($klass)),
$c->rinc('dissect_xdr_'.$self->reftype->idstrip);
}
@@ -359,7 +359,7 @@ BEGIN{::register_profile(
sub render_caller {
my ($self, $hfid) = @_;
my ($klass) = ref($self) =~ /([^:]+)$/;
- sprintf '%s(tvb, tree, xdrs, hf, %s)',
+ sprintf '%s(tvb, pinfo, tree, xdrs, hf, %s)',
$c->rinc('dissect_xdr_'.lc($klass)), $self->length || '~0';
}
@@ -447,7 +447,7 @@ BEGIN{::register_profile(
sub render_caller {
my ($self, $hfid) = @_;
my ($pname) = reverse split /__/, $hfid;
- sprintf 'dissect_xdr_array(tvb, tree, xdrs, hf, %s, %s, "%s", %s, %s)',
+ sprintf 'dissect_xdr_array(tvb, pinfo, tree, xdrs, hf, %s, %s, "%s", %s, %s)',
$c->rinc('ett_'.$self->idstrip),
$c->rinc("hf_$hfid\__$pname"),
$self->reftype->idstrip,
@@ -476,7 +476,7 @@ BEGIN{::register_profile(
sub render_caller {
my ($self, $hfid) = @_;
my ($pname) = reverse split /__/, $hfid;
- sprintf 'dissect_xdr_vector(tvb, tree, xdrs, hf, %s, %s, "%s", %s, %s)',
+ sprintf 'dissect_xdr_vector(tvb, pinfo, tree, xdrs, hf, %s, %s, "%s", %s, %s)',
$c->rinc('ett_'.$self->idstrip),
$c->rinc("hf_$hfid\__$pname"),
$self->reftype->idstrip,
@@ -857,7 +857,7 @@ __END__<<DUMMY # Dummy heredoc to disable perl syntax highlighting
my ($self, $ident) = @_;
return if $self->is_primitive;
%>
-static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
+static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf)
{
return <%= $self->dealias->render_caller($self->ident eq $ident ? undef : $ident) %>;
}
@@ -865,7 +865,7 @@ static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *
<% my ($self, $ident) = @_;
my $hfvar = $c->rinc('hf_'.$self->idstrip);
%>
-static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
+static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf)
{
goffset start;
proto_item *ti;
@@ -890,7 +890,7 @@ static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *
}
@@ Sym::Type::Enum#render_dissector
<% my ($self, $ident) = @_; %>
-static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
+static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf)
{
goffset start;
enum { DUMMY } es;
@@ -914,7 +914,7 @@ static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *
my ($self, $ident) = @_;
my $decl_type = $self->decl->type->idstrip;
%>
-static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf)
+static gboolean dissect_xdr_<%= $ident %>(tvbuff_t *tvb, packet_info *pinfo G_GNUC_UNUSED, proto_tree *tree, XDR *xdrs, int hf)
{
gboolean rc = TRUE;
goffset start;
--
2.51.0

3
fedora-42/SOURCES/libvirt-11.0.0.tar.xz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:01a176ff4042ad58cf83c09fe0925d6bc8eed0ecce1e0ee19b8ef4c1ffa3806e
size 9700388

3
fedora-42/SOURCES/zfs-2.3.4.tar.gz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:70bc4b6b22e5474faf46d4dad5717a6cdd5f85a9830012ae64014abbe52406fc
size 34387363

3
fedora-42/SOURCES/zfs-2.3.5.tar.gz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3b8f64583d114decb8ca5efecffaf233b22827c10ff27c84d79e93b7d363bbf6
size 34392768

3
fedora-42/SOURCES/zfs-2.4.0.tar.gz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:098909c9350707cca9f723a01309e5b4ef80231a0a823a735e6249d93122935b
size 34483126

3
fedora-42/SOURCES/zfs-2.4.1.tar.gz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a9080ce03a91550cb0405c3466a3a1dc6bf29b8a62cf6ea44a1f53a465021991
size 34497242

3
fedora-42/SOURCES/zfs-2.4.2.tar.gz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5f31def0989a7042d5003089b375f0ded75a5c4246f5935a2c1fd75dd70c4bb5
size 34522287

3
fedora-43/SOURCES/zfs-2.3.5.tar.gz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:89f9dec9a5c25a08bd11e738bdf75e24f81e99d4419551917593d49f4d483e8e
size 34404729

3
fedora-43/SOURCES/zfs-2.4.0.tar.gz

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:365df77dcc7d371a2c66ed9cce6723f2bd934a57f5743a12416c416c6dbb7624
size 34497904

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save