diff --git a/SOURCES/libvirt-Add-testdata-for-AMD-EPYC-7502.patch b/SOURCES/libvirt-Add-testdata-for-AMD-EPYC-7502.patch
new file mode 100644
index 0000000..1530f4e
--- /dev/null
+++ b/SOURCES/libvirt-Add-testdata-for-AMD-EPYC-7502.patch
@@ -0,0 +1,2173 @@
+From a2f2e97422de810517a77d8f098564e3b6c0f7c2 Mon Sep 17 00:00:00 2001
+Message-Id: <a2f2e97422de810517a77d8f098564e3b6c0f7c2@dist-git>
+From: Markus Schade <markus.schade@hetzner.com>
+Date: Thu, 8 Oct 2020 18:01:24 +0200
+Subject: [PATCH] Add testdata for AMD EPYC 7502
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Markus Schade <markus.schade@hetzner.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit e06590f1708a599286f3ee3690b3dc50ee525d40)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1861506
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Message-Id: <2efe44ce5c929916c92656803d39635ae7c189b9.1602172344.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/cputest.c                               |    1 +
+ ...86_64-cpuid-EPYC-7502-32-Core-disabled.xml |    9 +
+ ...x86_64-cpuid-EPYC-7502-32-Core-enabled.xml |   11 +
+ .../x86_64-cpuid-EPYC-7502-32-Core-guest.xml  |   42 +
+ .../x86_64-cpuid-EPYC-7502-32-Core-host.xml   |   43 +
+ .../x86_64-cpuid-EPYC-7502-32-Core-json.xml   |   31 +
+ .../x86_64-cpuid-EPYC-7502-32-Core.json       | 1866 +++++++++++++++++
+ .../x86_64-cpuid-EPYC-7502-32-Core.sig        |    4 +
+ .../x86_64-cpuid-EPYC-7502-32-Core.xml        |   66 +
+ 9 files changed, 2073 insertions(+)
+ create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-disabled.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-enabled.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.json
+ create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.sig
+ create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.xml
+
+diff --git a/tests/cputest.c b/tests/cputest.c
+index 68e8eb0290..388174eba7 100644
+--- a/tests/cputest.c
++++ b/tests/cputest.c
+@@ -1242,6 +1242,7 @@ mymain(void)
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "Hygon-C86-7185-32-core", JSON_HOST);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "EPYC-7601-32-Core", JSON_HOST);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "EPYC-7601-32-Core-ibpb", JSON_MODELS_REQUIRED);
++    DO_TEST_CPUID(VIR_ARCH_X86_64, "EPYC-7502-32-Core", JSON_MODELS);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "FX-8150", JSON_NONE);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "Opteron-1352", JSON_NONE);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "Opteron-2350", JSON_HOST);
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-disabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-disabled.xml
+new file mode 100644
+index 0000000000..ca71b9efb5
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-disabled.xml
+@@ -0,0 +1,9 @@
++<!-- Features disabled by QEMU -->
++<cpudata arch='x86'>
++  <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x08000008' edx='0x10000000'/>
++  <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x00001000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/>
++  <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01423408' edx='0x00000000'/>
++  <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x000014f6'/>
++</cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-enabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-enabled.xml
+new file mode 100644
+index 0000000000..09a9952c27
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-enabled.xml
+@@ -0,0 +1,11 @@
++<!-- Features enabled by QEMU -->
++<cpudata arch='x86'>
++  <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0xf7f83203' edx='0x078bfbff'/>
++  <cpuid eax_in='0x00000006' ecx_in='0x00' eax='0x00000004' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x219c01ab' ecx='0x00400004' edx='0xac000000'/>
++  <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x0000000f' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x008003f7' edx='0x2e500800'/>
++  <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x03009205' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/>
++  <msr index='0x10a' edx='0x00000000' eax='0x00000069'/>
++</cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml
+new file mode 100644
+index 0000000000..1320f65a58
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml
+@@ -0,0 +1,42 @@
++<cpu mode='custom' match='exact'>
++  <model fallback='forbid'>EPYC-IBPB</model>
++  <vendor>AMD</vendor>
++  <feature policy='require' name='ht'/>
++  <feature policy='require' name='osxsave'/>
++  <feature policy='require' name='cmt'/>
++  <feature policy='require' name='clwb'/>
++  <feature policy='require' name='umip'/>
++  <feature policy='require' name='rdpid'/>
++  <feature policy='require' name='xsaves'/>
++  <feature policy='require' name='mbm_total'/>
++  <feature policy='require' name='mbm_local'/>
++  <feature policy='require' name='cmp_legacy'/>
++  <feature policy='require' name='extapic'/>
++  <feature policy='require' name='ibs'/>
++  <feature policy='require' name='skinit'/>
++  <feature policy='require' name='wdt'/>
++  <feature policy='require' name='tce'/>
++  <feature policy='require' name='topoext'/>
++  <feature policy='require' name='perfctr_core'/>
++  <feature policy='require' name='perfctr_nb'/>
++  <feature policy='require' name='invtsc'/>
++  <feature policy='require' name='clzero'/>
++  <feature policy='require' name='xsaveerptr'/>
++  <feature policy='require' name='wbnoinvd'/>
++  <feature policy='require' name='amd-stibp'/>
++  <feature policy='require' name='amd-ssbd'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='lbrv'/>
++  <feature policy='require' name='svm-lock'/>
++  <feature policy='require' name='nrip-save'/>
++  <feature policy='require' name='tsc-scale'/>
++  <feature policy='require' name='vmcb-clean'/>
++  <feature policy='require' name='flushbyasid'/>
++  <feature policy='require' name='decodeassists'/>
++  <feature policy='require' name='pause-filter'/>
++  <feature policy='require' name='pfthreshold'/>
++  <feature policy='require' name='rdctl-no'/>
++  <feature policy='require' name='skip-l1dfl-vmentry'/>
++  <feature policy='require' name='mds-no'/>
++  <feature policy='require' name='pschange-mc-no'/>
++</cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml
+new file mode 100644
+index 0000000000..37905ec812
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml
+@@ -0,0 +1,43 @@
++<cpu>
++  <arch>x86_64</arch>
++  <model>EPYC-IBPB</model>
++  <vendor>AMD</vendor>
++  <feature name='ht'/>
++  <feature name='osxsave'/>
++  <feature name='cmt'/>
++  <feature name='clwb'/>
++  <feature name='umip'/>
++  <feature name='rdpid'/>
++  <feature name='xsaves'/>
++  <feature name='mbm_total'/>
++  <feature name='mbm_local'/>
++  <feature name='cmp_legacy'/>
++  <feature name='extapic'/>
++  <feature name='ibs'/>
++  <feature name='skinit'/>
++  <feature name='wdt'/>
++  <feature name='tce'/>
++  <feature name='topoext'/>
++  <feature name='perfctr_core'/>
++  <feature name='perfctr_nb'/>
++  <feature name='invtsc'/>
++  <feature name='clzero'/>
++  <feature name='xsaveerptr'/>
++  <feature name='wbnoinvd'/>
++  <feature name='amd-stibp'/>
++  <feature name='amd-ssbd'/>
++  <feature name='npt'/>
++  <feature name='lbrv'/>
++  <feature name='svm-lock'/>
++  <feature name='nrip-save'/>
++  <feature name='tsc-scale'/>
++  <feature name='vmcb-clean'/>
++  <feature name='flushbyasid'/>
++  <feature name='decodeassists'/>
++  <feature name='pause-filter'/>
++  <feature name='pfthreshold'/>
++  <feature name='rdctl-no'/>
++  <feature name='skip-l1dfl-vmentry'/>
++  <feature name='mds-no'/>
++  <feature name='pschange-mc-no'/>
++</cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml
+new file mode 100644
+index 0000000000..225cf63852
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml
+@@ -0,0 +1,31 @@
++<cpu mode='custom' match='exact'>
++  <model fallback='forbid'>EPYC-IBPB</model>
++  <vendor>AMD</vendor>
++  <feature policy='require' name='x2apic'/>
++  <feature policy='require' name='tsc-deadline'/>
++  <feature policy='require' name='hypervisor'/>
++  <feature policy='require' name='tsc_adjust'/>
++  <feature policy='require' name='clwb'/>
++  <feature policy='require' name='umip'/>
++  <feature policy='require' name='rdpid'/>
++  <feature policy='require' name='spec-ctrl'/>
++  <feature policy='require' name='stibp'/>
++  <feature policy='require' name='arch-capabilities'/>
++  <feature policy='require' name='ssbd'/>
++  <feature policy='require' name='xsaves'/>
++  <feature policy='require' name='cmp_legacy'/>
++  <feature policy='require' name='perfctr_core'/>
++  <feature policy='require' name='clzero'/>
++  <feature policy='require' name='xsaveerptr'/>
++  <feature policy='require' name='wbnoinvd'/>
++  <feature policy='require' name='amd-stibp'/>
++  <feature policy='require' name='amd-ssbd'/>
++  <feature policy='require' name='virt-ssbd'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='nrip-save'/>
++  <feature policy='require' name='rdctl-no'/>
++  <feature policy='require' name='skip-l1dfl-vmentry'/>
++  <feature policy='require' name='mds-no'/>
++  <feature policy='require' name='pschange-mc-no'/>
++  <feature policy='disable' name='monitor'/>
++</cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.json b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.json
+new file mode 100644
+index 0000000000..06c265d829
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.json
+@@ -0,0 +1,1866 @@
++{
++  "return": {
++    "model": {
++      "name": "base",
++      "props": {
++        "vmx-entry-load-rtit-ctl": false,
++        "phys-bits": 0,
++        "core-id": -1,
++        "xlevel": 2147483679,
++        "cmov": true,
++        "ia64": false,
++        "ssb-no": false,
++        "aes": true,
++        "vmx-apicv-xapic": false,
++        "mmx": true,
++        "arat": true,
++        "rdpid": true,
++        "vmx-page-walk-5": false,
++        "vmx-page-walk-4": false,
++        "vmx-desc-exit": false,
++        "gfni": false,
++        "ibrs-all": false,
++        "pause-filter": false,
++        "xsavec": true,
++        "intel-pt": false,
++        "vmx-cr8-store-exit": false,
++        "hv-frequencies": false,
++        "tsc-frequency": 0,
++        "vmx-rdseed-exit": false,
++        "xd": true,
++        "x-intel-pt-auto-level": true,
++        "hv-vendor-id": "",
++        "vmx-eptp-switching": false,
++        "kvm_asyncpf": true,
++        "kvm-asyncpf": true,
++        "perfctr_core": true,
++        "perfctr-core": true,
++        "mpx": false,
++        "avx512cd": false,
++        "pbe": false,
++        "decodeassists": false,
++        "vmx-exit-clear-bndcfgs": false,
++        "vmx-exit-load-efer": false,
++        "sse4_1": true,
++        "sse4-1": true,
++        "sse4.1": true,
++        "family": 23,
++        "legacy-cache": true,
++        "vmx-vmwrite-vmexit-fields": false,
++        "vmx-vnmi": false,
++        "vmx-true-ctls": false,
++        "host-phys-bits-limit": 0,
++        "vmx-ept-execonly": false,
++        "vmx-exit-save-efer": false,
++        "vmx-invept-all-context": false,
++        "vmware-cpuid-freq": true,
++        "wbnoinvd": true,
++        "avx512f": false,
++        "xcrypt": false,
++        "hv-runtime": false,
++        "hv-stimer-direct": false,
++        "mce": true,
++        "mca": true,
++        "msr": true,
++        "thread-id": -1,
++        "vmx-exit-load-pat": false,
++        "vmx-intr-exit": false,
++        "min-level": 16,
++        "vmx-flexpriority": false,
++        "xgetbv1": true,
++        "cid": false,
++        "hv-relaxed": false,
++        "avx512-bf16": false,
++        "ds": false,
++        "hv-crash": false,
++        "fxsr": true,
++        "vmx-cr8-load-exit": false,
++        "xsaveopt": true,
++        "vmx-apicv-vid": false,
++        "vmx-exit-save-pat": false,
++        "tsx-ctrl": false,
++        "xtpr": false,
++        "vmx-ple": false,
++        "hv-evmcs": false,
++        "avx512-vpopcntdq": false,
++        "phe": false,
++        "avx512vl": false,
++        "extapic": false,
++        "vmx-vmfunc": false,
++        "3dnowprefetch": true,
++        "vmx-activity-shutdown": false,
++        "avx512vbmi2": false,
++        "cr8legacy": true,
++        "vmx-encls-exit": false,
++        "stibp": true,
++        "vmx-msr-bitmap": false,
++        "cpuid-0xb": true,
++        "xcrypt-en": false,
++        "vmx-mwait-exit": false,
++        "kvm_pv_eoi": true,
++        "vmx-pml": false,
++        "apic-id": 4294967295,
++        "vmx-nmi-exit": false,
++        "vmx-invept-single-context-noglobals": false,
++        "pn": false,
++        "rsba": false,
++        "dca": false,
++        "vmx-unrestricted-guest": false,
++        "vendor": "AuthenticAMD",
++        "hv-ipi": false,
++        "vmx-cr3-store-noexit": false,
++        "pku": false,
++        "smx": false,
++        "cmp-legacy": true,
++        "cmp_legacy": true,
++        "node-id": -1,
++        "avx512-4fmaps": false,
++        "vmcb_clean": false,
++        "vmcb-clean": false,
++        "hle": false,
++        "amd-no-ssb": false,
++        "3dnowext": false,
++        "npt": true,
++        "rdctl-no": true,
++        "vmx-invvpid": false,
++        "memory": "/machine/unattached/system[0]",
++        "clwb": true,
++        "lbrv": false,
++        "adx": true,
++        "ss": false,
++        "pni": true,
++        "svm_lock": false,
++        "svm-lock": false,
++        "pfthreshold": false,
++        "smap": true,
++        "smep": true,
++        "vmx-invpcid-exit": false,
++        "x2apic": true,
++        "avx512vnni": false,
++        "avx512vbmi": false,
++        "vmx-apicv-x2apic": false,
++        "hv-stimer": false,
++        "kvm-pv-sched-yield": true,
++        "vmx-invlpg-exit": false,
++        "x-hv-synic-kvm-only": false,
++        "vmx-invvpid-all-context": false,
++        "i64": true,
++        "vmx-activity-hlt": false,
++        "flushbyasid": false,
++        "f16c": true,
++        "vmx-exit-ack-intr": false,
++        "ace2-en": false,
++        "pae": true,
++        "pat": true,
++        "sse": true,
++        "die-id": -1,
++        "vmx-tsc-offset": false,
++        "phe-en": false,
++        "kvm_nopiodelay": true,
++        "kvm-nopiodelay": true,
++        "tm": false,
++        "kvmclock-stable-bit": true,
++        "vmx-rdtsc-exit": false,
++        "hypervisor": true,
++        "vmx-rdtscp-exit": false,
++        "socket-id": -1,
++        "mds-no": true,
++        "pcommit": false,
++        "vmx-vpid": false,
++        "syscall": true,
++        "level": 16,
++        "avx512dq": false,
++        "x-migrate-smi-count": true,
++        "svm": true,
++        "full-cpuid-auto-level": true,
++        "hv-reset": false,
++        "invtsc": false,
++        "vmx-monitor-exit": false,
++        "sse3": true,
++        "sse2": true,
++        "ssbd": true,
++        "vmx-wbinvd-exit": false,
++        "est": false,
++        "kvm-poll-control": true,
++        "kvm_poll_control": true,
++        "avx512ifma": false,
++        "tm2": false,
++        "kvm-pv-eoi": true,
++        "kvm-pv-ipi": true,
++        "cx8": true,
++        "vmx-invvpid-single-addr": false,
++        "waitpkg": false,
++        "cldemote": false,
++        "vmx-ept": false,
++        "hv-reenlightenment": false,
++        "kvm_mmu": false,
++        "kvm-mmu": false,
++        "sse4-2": true,
++        "sse4.2": true,
++        "sse4_2": true,
++        "pge": true,
++        "fill-mtrr-mask": true,
++        "avx512bitalg": false,
++        "vmx-entry-load-bndcfgs": false,
++        "nodeid_msr": false,
++        "pdcm": false,
++        "vmx-exit-clear-rtit-ctl": false,
++        "model": 49,
++        "movbe": true,
++        "nrip_save": true,
++        "nrip-save": true,
++        "vmx-pause-exit": false,
++        "ssse3": true,
++        "kvm_pv_unhalt": true,
++        "sse4a": true,
++        "invpcid": false,
++        "pdpe1gb": true,
++        "tsc-deadline": true,
++        "skip-l1dfl-vmentry": true,
++        "vmx-exit-load-perf-global-ctrl": false,
++        "fma": true,
++        "cx16": true,
++        "de": true,
++        "enforce": false,
++        "stepping": 0,
++        "xsave": true,
++        "clflush": true,
++        "skinit": false,
++        "tsc": true,
++        "tce": false,
++        "fpu": true,
++        "ds-cpl": false,
++        "ds_cpl": false,
++        "ibs": false,
++        "fma4": false,
++        "host-phys-bits": false,
++        "vmx-exit-nosave-debugctl": false,
++        "vmx-invept": false,
++        "la57": false,
++        "osvw": true,
++        "check": true,
++        "hv-spinlocks": 4294967295,
++        "vmx-eptad": false,
++        "pmu": false,
++        "vmx-entry-noload-debugctl": false,
++        "pmm": false,
++        "apic": true,
++        "spec-ctrl": true,
++        "vmx-posted-intr": false,
++        "vmx-apicv-register": false,
++        "min-xlevel2": 0,
++        "tsc-adjust": true,
++        "tsc_adjust": true,
++        "kvm-steal-time": true,
++        "kvm_steal_time": true,
++        "kvmclock": true,
++        "vmx-zero-len-inject": false,
++        "l3-cache": true,
++        "pschange-mc-no": true,
++        "vmx-rdrand-exit": false,
++        "lwp": false,
++        "hv-passthrough": false,
++        "amd-ssbd": true,
++        "ibpb": true,
++        "xop": false,
++        "core-capability": false,
++        "avx": true,
++        "vmx-invept-single-context": false,
++        "movdiri": false,
++        "avx512bw": false,
++        "acpi": false,
++        "ace2": false,
++        "fsgsbase": true,
++        "hv-vapic": false,
++        "vmx-ept-1gb": false,
++        "vmx-ept-2mb": false,
++        "ht": false,
++        "vmx-io-exit": false,
++        "nx": true,
++        "pclmulqdq": true,
++        "mmxext": true,
++        "popcnt": true,
++        "vaes": false,
++        "xsaves": true,
++        "movdir64b": false,
++        "vmx-shadow-vmcs": false,
++        "tcg-cpuid": true,
++        "lm": true,
++        "vmx-exit-save-preemption-timer": false,
++        "vmx-entry-load-pat": false,
++        "vmx-entry-load-perf-global-ctrl": false,
++        "vmx-io-bitmap": false,
++        "vmx-store-lma": false,
++        "umip": true,
++        "vmx-movdr-exit": false,
++        "avx2": true,
++        "pse": true,
++        "pclmuldq": true,
++        "sep": true,
++        "vmx-cr3-load-noexit": false,
++        "virt-ssbd": true,
++        "x-hv-max-vps": -1,
++        "nodeid-msr": false,
++        "md-clear": false,
++        "split-lock-detect": false,
++        "kvm": true,
++        "misalignsse": true,
++        "min-xlevel": 2147483679,
++        "realized": false,
++        "kvm-pv-unhalt": true,
++        "bmi2": true,
++        "bmi1": true,
++        "tsc_scale": false,
++        "tsc-scale": false,
++        "topoext": false,
++        "amd-stibp": true,
++        "hv-vpindex": false,
++        "hv-no-nonarch-coresharing": "off",
++        "vmx-preemption-timer": false,
++        "xlevel2": 0,
++        "clflushopt": true,
++        "vmx-vnmi-pending": false,
++        "kvm-no-smi-migration": false,
++        "monitor": false,
++        "vmx-vintr-pending": false,
++        "avx512er": false,
++        "pmm-en": false,
++        "taa-no": false,
++        "pcid": false,
++        "vmx-secondary-ctls": false,
++        "arch-capabilities": true,
++        "vmx-xsaves": false,
++        "clzero": true,
++        "3dnow": false,
++        "erms": false,
++        "x-force-features": false,
++        "vmx-entry-ia32e-mode": false,
++        "lahf-lm": true,
++        "lahf_lm": true,
++        "vmx-ins-outs": false,
++        "vpclmulqdq": false,
++        "xstore": false,
++        "fxsr-opt": true,
++        "fxsr_opt": true,
++        "hv-synic": false,
++        "rtm": false,
++        "kvm-hint-dedicated": false,
++        "lmce": false,
++        "hv-time": false,
++        "perfctr_nb": false,
++        "perfctr-nb": false,
++        "hv-tlbflush": false,
++        "ffxsr": true,
++        "rdrand": true,
++        "rdseed": true,
++        "avx512-4vnniw": false,
++        "vme": true,
++        "vmx": false,
++        "dtes64": false,
++        "mtrr": true,
++        "rdtscp": true,
++        "xsaveerptr": true,
++        "pse36": true,
++        "kvm-pv-tlb-flush": true,
++        "vmx-activity-wait-sipi": false,
++        "tbm": false,
++        "vmx-rdpmc-exit": false,
++        "wdt": false,
++        "vmx-entry-load-efer": false,
++        "level-func7": 0,
++        "vmx-mtf": false,
++        "pause_filter": false,
++        "model-id": "AMD EPYC 7502 32-Core Processor                ",
++        "sha-ni": true,
++        "abm": true,
++        "vmx-ept-advanced-exitinfo": false,
++        "avx512pf": false,
++        "vmx-hlt-exit": false,
++        "xstore-en": false
++      }
++    }
++  },
++  "id": "model-expansion"
++}
++
++{
++  "return": [
++    {
++      "name": "max",
++      "typename": "max-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": false
++    },
++    {
++      "name": "host",
++      "typename": "host-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": false
++    },
++    {
++      "name": "base",
++      "typename": "base-x86_64-cpu",
++      "unavailable-features": [],
++      "static": true,
++      "migration-safe": true
++    },
++    {
++      "name": "qemu64-v1",
++      "typename": "qemu64-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "qemu64",
++      "typename": "qemu64-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "qemu64-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "qemu32-v1",
++      "typename": "qemu32-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "qemu32",
++      "typename": "qemu32-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "qemu32-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "phenom-v1",
++      "typename": "phenom-v1-x86_64-cpu",
++      "unavailable-features": [
++        "3dnowext",
++        "3dnow"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "phenom",
++      "typename": "phenom-x86_64-cpu",
++      "unavailable-features": [
++        "3dnowext",
++        "3dnow"
++      ],
++      "alias-of": "phenom-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "pentium3-v1",
++      "typename": "pentium3-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "pentium3",
++      "typename": "pentium3-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "pentium3-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "pentium2-v1",
++      "typename": "pentium2-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "pentium2",
++      "typename": "pentium2-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "pentium2-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "pentium-v1",
++      "typename": "pentium-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "pentium",
++      "typename": "pentium-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "pentium-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "n270-v1",
++      "typename": "n270-v1-x86_64-cpu",
++      "unavailable-features": [
++        "ss"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "n270",
++      "typename": "n270-x86_64-cpu",
++      "unavailable-features": [
++        "ss"
++      ],
++      "alias-of": "n270-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "kvm64-v1",
++      "typename": "kvm64-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "kvm64",
++      "typename": "kvm64-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "kvm64-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "kvm32-v1",
++      "typename": "kvm32-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "kvm32",
++      "typename": "kvm32-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "kvm32-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "coreduo-v1",
++      "typename": "coreduo-v1-x86_64-cpu",
++      "unavailable-features": [
++        "ss"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "coreduo",
++      "typename": "coreduo-x86_64-cpu",
++      "unavailable-features": [
++        "ss"
++      ],
++      "alias-of": "coreduo-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "core2duo-v1",
++      "typename": "core2duo-v1-x86_64-cpu",
++      "unavailable-features": [
++        "ss"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "core2duo",
++      "typename": "core2duo-x86_64-cpu",
++      "unavailable-features": [
++        "ss"
++      ],
++      "alias-of": "core2duo-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "athlon-v1",
++      "typename": "athlon-v1-x86_64-cpu",
++      "unavailable-features": [
++        "3dnowext",
++        "3dnow"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "athlon",
++      "typename": "athlon-x86_64-cpu",
++      "unavailable-features": [
++        "3dnowext",
++        "3dnow"
++      ],
++      "alias-of": "athlon-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Westmere-v2",
++      "typename": "Westmere-v2-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Westmere-v1",
++      "typename": "Westmere-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Westmere-IBRS",
++      "typename": "Westmere-IBRS-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "Westmere-v2",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Westmere",
++      "typename": "Westmere-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "Westmere-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Snowridge-v2",
++      "typename": "Snowridge-v2-x86_64-cpu",
++      "unavailable-features": [
++        "erms",
++        "gfni",
++        "cldemote",
++        "movdiri",
++        "movdir64b",
++        "core-capability",
++        "split-lock-detect"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Snowridge-v1",
++      "typename": "Snowridge-v1-x86_64-cpu",
++      "unavailable-features": [
++        "erms",
++        "mpx",
++        "gfni",
++        "cldemote",
++        "movdiri",
++        "movdir64b",
++        "core-capability",
++        "mpx",
++        "mpx",
++        "split-lock-detect"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Snowridge",
++      "typename": "Snowridge-x86_64-cpu",
++      "unavailable-features": [
++        "erms",
++        "mpx",
++        "gfni",
++        "cldemote",
++        "movdiri",
++        "movdir64b",
++        "core-capability",
++        "mpx",
++        "mpx",
++        "split-lock-detect"
++      ],
++      "alias-of": "Snowridge-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Server-v3",
++      "typename": "Skylake-Server-v3-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Server-v2",
++      "typename": "Skylake-Server-v2-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Server-v1",
++      "typename": "Skylake-Server-v1-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Server-noTSX-IBRS",
++      "typename": "Skylake-Server-noTSX-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "alias-of": "Skylake-Server-v3",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Server-IBRS",
++      "typename": "Skylake-Server-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "alias-of": "Skylake-Server-v2",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Server",
++      "typename": "Skylake-Server-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "alias-of": "Skylake-Server-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Client-v3",
++      "typename": "Skylake-Client-v3-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Client-v2",
++      "typename": "Skylake-Client-v2-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Client-v1",
++      "typename": "Skylake-Client-v1-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Client-noTSX-IBRS",
++      "typename": "Skylake-Client-noTSX-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid"
++      ],
++      "alias-of": "Skylake-Client-v3",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Client-IBRS",
++      "typename": "Skylake-Client-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm"
++      ],
++      "alias-of": "Skylake-Client-v2",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Client",
++      "typename": "Skylake-Client-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm"
++      ],
++      "alias-of": "Skylake-Client-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "SandyBridge-v2",
++      "typename": "SandyBridge-v2-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "SandyBridge-v1",
++      "typename": "SandyBridge-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "SandyBridge-IBRS",
++      "typename": "SandyBridge-IBRS-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "SandyBridge-v2",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "SandyBridge",
++      "typename": "SandyBridge-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "SandyBridge-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Penryn-v1",
++      "typename": "Penryn-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Penryn",
++      "typename": "Penryn-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "Penryn-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G5-v1",
++      "typename": "Opteron_G5-v1-x86_64-cpu",
++      "unavailable-features": [
++        "xop",
++        "fma4",
++        "tbm"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G5",
++      "typename": "Opteron_G5-x86_64-cpu",
++      "unavailable-features": [
++        "xop",
++        "fma4",
++        "tbm"
++      ],
++      "alias-of": "Opteron_G5-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G4-v1",
++      "typename": "Opteron_G4-v1-x86_64-cpu",
++      "unavailable-features": [
++        "xop",
++        "fma4"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G4",
++      "typename": "Opteron_G4-x86_64-cpu",
++      "unavailable-features": [
++        "xop",
++        "fma4"
++      ],
++      "alias-of": "Opteron_G4-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G3-v1",
++      "typename": "Opteron_G3-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G3",
++      "typename": "Opteron_G3-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "Opteron_G3-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G2-v1",
++      "typename": "Opteron_G2-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G2",
++      "typename": "Opteron_G2-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "Opteron_G2-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G1-v1",
++      "typename": "Opteron_G1-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G1",
++      "typename": "Opteron_G1-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "Opteron_G1-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Nehalem-v2",
++      "typename": "Nehalem-v2-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Nehalem-v1",
++      "typename": "Nehalem-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Nehalem-IBRS",
++      "typename": "Nehalem-IBRS-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "Nehalem-v2",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Nehalem",
++      "typename": "Nehalem-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "Nehalem-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "KnightsMill-v1",
++      "typename": "KnightsMill-v1-x86_64-cpu",
++      "unavailable-features": [
++        "ss",
++        "erms",
++        "avx512f",
++        "avx512pf",
++        "avx512er",
++        "avx512cd",
++        "avx512-vpopcntdq",
++        "avx512-4vnniw",
++        "avx512-4fmaps",
++        "avx512f",
++        "avx512f",
++        "avx512f"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "KnightsMill",
++      "typename": "KnightsMill-x86_64-cpu",
++      "unavailable-features": [
++        "ss",
++        "erms",
++        "avx512f",
++        "avx512pf",
++        "avx512er",
++        "avx512cd",
++        "avx512-vpopcntdq",
++        "avx512-4vnniw",
++        "avx512-4fmaps",
++        "avx512f",
++        "avx512f",
++        "avx512f"
++      ],
++      "alias-of": "KnightsMill-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "IvyBridge-v2",
++      "typename": "IvyBridge-v2-x86_64-cpu",
++      "unavailable-features": [
++        "erms"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "IvyBridge-v1",
++      "typename": "IvyBridge-v1-x86_64-cpu",
++      "unavailable-features": [
++        "erms"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "IvyBridge-IBRS",
++      "typename": "IvyBridge-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "erms"
++      ],
++      "alias-of": "IvyBridge-v2",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "IvyBridge",
++      "typename": "IvyBridge-x86_64-cpu",
++      "unavailable-features": [
++        "erms"
++      ],
++      "alias-of": "IvyBridge-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Server-v2",
++      "typename": "Icelake-Server-v2-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "gfni",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "la57",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Server-v1",
++      "typename": "Icelake-Server-v1-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "gfni",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "la57",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Server-noTSX",
++      "typename": "Icelake-Server-noTSX-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "gfni",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "la57",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "alias-of": "Icelake-Server-v2",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Server",
++      "typename": "Icelake-Server-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "gfni",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "la57",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "alias-of": "Icelake-Server-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Client-v2",
++      "typename": "Icelake-Client-v2-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "gfni",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Client-v1",
++      "typename": "Icelake-Client-v1-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "gfni",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Client-noTSX",
++      "typename": "Icelake-Client-noTSX-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "gfni",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "pku"
++      ],
++      "alias-of": "Icelake-Client-v2",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Client",
++      "typename": "Icelake-Client-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "gfni",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "pku"
++      ],
++      "alias-of": "Icelake-Client-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell-v4",
++      "typename": "Haswell-v4-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell-v3",
++      "typename": "Haswell-v3-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell-v2",
++      "typename": "Haswell-v2-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell-v1",
++      "typename": "Haswell-v1-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell-noTSX-IBRS",
++      "typename": "Haswell-noTSX-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid"
++      ],
++      "alias-of": "Haswell-v4",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell-noTSX",
++      "typename": "Haswell-noTSX-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid"
++      ],
++      "alias-of": "Haswell-v2",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell-IBRS",
++      "typename": "Haswell-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm"
++      ],
++      "alias-of": "Haswell-v3",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell",
++      "typename": "Haswell-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm"
++      ],
++      "alias-of": "Haswell-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "EPYC-v3",
++      "typename": "EPYC-v3-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "EPYC-v2",
++      "typename": "EPYC-v2-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "EPYC-v1",
++      "typename": "EPYC-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "EPYC-Rome-v1",
++      "typename": "EPYC-Rome-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "EPYC-Rome",
++      "typename": "EPYC-Rome-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "EPYC-Rome-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "EPYC-IBPB",
++      "typename": "EPYC-IBPB-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "EPYC-v2",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "EPYC",
++      "typename": "EPYC-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "EPYC-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Dhyana-v1",
++      "typename": "Dhyana-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Dhyana",
++      "typename": "Dhyana-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "Dhyana-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Denverton-v1",
++      "typename": "Denverton-v1-x86_64-cpu",
++      "unavailable-features": [
++        "erms",
++        "mpx",
++        "mpx",
++        "mpx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Denverton",
++      "typename": "Denverton-x86_64-cpu",
++      "unavailable-features": [
++        "erms",
++        "mpx",
++        "mpx",
++        "mpx"
++      ],
++      "alias-of": "Denverton-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Cooperlake-v1",
++      "typename": "Cooperlake-v1-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512vnni",
++        "avx512-bf16",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku",
++        "ibrs-all"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Cooperlake",
++      "typename": "Cooperlake-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512vnni",
++        "avx512-bf16",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku",
++        "ibrs-all"
++      ],
++      "alias-of": "Cooperlake-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Conroe-v1",
++      "typename": "Conroe-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Conroe",
++      "typename": "Conroe-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "Conroe-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Cascadelake-Server-v3",
++      "typename": "Cascadelake-Server-v3-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512vnni",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku",
++        "ibrs-all"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Cascadelake-Server-v2",
++      "typename": "Cascadelake-Server-v2-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512vnni",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku",
++        "ibrs-all"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Cascadelake-Server-v1",
++      "typename": "Cascadelake-Server-v1-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512vnni",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Cascadelake-Server-noTSX",
++      "typename": "Cascadelake-Server-noTSX-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512vnni",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku",
++        "ibrs-all"
++      ],
++      "alias-of": "Cascadelake-Server-v3",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Cascadelake-Server",
++      "typename": "Cascadelake-Server-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512vnni",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "alias-of": "Cascadelake-Server-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell-v4",
++      "typename": "Broadwell-v4-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell-v3",
++      "typename": "Broadwell-v3-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell-v2",
++      "typename": "Broadwell-v2-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell-v1",
++      "typename": "Broadwell-v1-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell-noTSX-IBRS",
++      "typename": "Broadwell-noTSX-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid"
++      ],
++      "alias-of": "Broadwell-v4",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell-noTSX",
++      "typename": "Broadwell-noTSX-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "erms",
++        "invpcid"
++      ],
++      "alias-of": "Broadwell-v2",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell-IBRS",
++      "typename": "Broadwell-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm"
++      ],
++      "alias-of": "Broadwell-v3",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell",
++      "typename": "Broadwell-x86_64-cpu",
++      "unavailable-features": [
++        "pcid",
++        "hle",
++        "erms",
++        "invpcid",
++        "rtm"
++      ],
++      "alias-of": "Broadwell-v1",
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "486-v1",
++      "typename": "486-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "486",
++      "typename": "486-x86_64-cpu",
++      "unavailable-features": [],
++      "alias-of": "486-v1",
++      "static": false,
++      "migration-safe": true
++    }
++  ],
++  "id": "definitions"
++}
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.sig b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.sig
+new file mode 100644
+index 0000000000..cf54739de9
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.sig
+@@ -0,0 +1,4 @@
++830f10
++family:    23 (0x17)
++model:     49 (0x31)
++stepping:   0 (0x00)
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.xml
+new file mode 100644
+index 0000000000..d6753065b9
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.xml
+@@ -0,0 +1,66 @@
++<!-- AMD EPYC 7502 32-Core Processor -->
++<cpudata arch='x86'>
++  <cpuid eax_in='0x00000000' ecx_in='0x00' eax='0x00000010' ebx='0x68747541' ecx='0x444d4163' edx='0x69746e65'/>
++  <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00830f10' ebx='0x31400800' ecx='0x7ed8320b' edx='0x178bfbff'/>
++  <cpuid eax_in='0x00000002' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000003' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000005' ecx_in='0x00' eax='0x00000040' ebx='0x00000040' ecx='0x00000003' edx='0x00000011'/>
++  <cpuid eax_in='0x00000006' ecx_in='0x00' eax='0x00000004' ebx='0x00000000' ecx='0x00000001' edx='0x00000000'/>
++  <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x219c91a9' ecx='0x00400004' edx='0x00000000'/>
++  <cpuid eax_in='0x00000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000009' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000b' ecx_in='0x00' eax='0x00000001' ebx='0x00000002' ecx='0x00000100' edx='0x00000031'/>
++  <cpuid eax_in='0x0000000b' ecx_in='0x01' eax='0x00000007' ebx='0x00000040' ecx='0x00000201' edx='0x00000031'/>
++  <cpuid eax_in='0x0000000c' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000d' ecx_in='0x00' eax='0x00000207' ebx='0x00000340' ecx='0x00000380' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x0000000f' ebx='0x00000340' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000d' ecx_in='0x02' eax='0x00000100' ebx='0x00000240' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000d' ecx_in='0x09' eax='0x00000040' ebx='0x00000340' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000e' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000f' ecx_in='0x00' eax='0x00000000' ebx='0x000000ff' ecx='0x00000000' edx='0x00000002'/>
++  <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000000' ebx='0x00000040' ecx='0x000000ff' edx='0x00000007'/>
++  <cpuid eax_in='0x00000010' ecx_in='0x00' eax='0x00000000' ebx='0x00000002' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000010' ecx_in='0x01' eax='0x0000000f' ebx='0x00000000' ecx='0x00000004' edx='0x0000000f'/>
++  <cpuid eax_in='0x20000000' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000000' ecx_in='0x00' eax='0x80000020' ebx='0x68747541' ecx='0x444d4163' edx='0x69746e65'/>
++  <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00830f10' ebx='0x40000000' ecx='0x75c237ff' edx='0x2fd3fbff'/>
++  <cpuid eax_in='0x80000002' ecx_in='0x00' eax='0x20444d41' ebx='0x43595045' ecx='0x30353720' edx='0x32332032'/>
++  <cpuid eax_in='0x80000003' ecx_in='0x00' eax='0x726f432d' ebx='0x72502065' ecx='0x7365636f' edx='0x20726f73'/>
++  <cpuid eax_in='0x80000004' ecx_in='0x00' eax='0x20202020' ebx='0x20202020' ecx='0x20202020' edx='0x00202020'/>
++  <cpuid eax_in='0x80000005' ecx_in='0x00' eax='0xff40ff40' ebx='0xff40ff40' ecx='0x20080140' edx='0x20080140'/>
++  <cpuid eax_in='0x80000006' ecx_in='0x00' eax='0x48006400' ebx='0x68006400' ecx='0x02006140' edx='0x04009140'/>
++  <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x0000001b' ecx='0x00000000' edx='0x00006799'/>
++  <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00003030' ebx='0x018cf757' ecx='0x0000703f' edx='0x00010000'/>
++  <cpuid eax_in='0x80000009' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000001' ebx='0x00008000' ecx='0x00000000' edx='0x0013bcff'/>
++  <cpuid eax_in='0x8000000b' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000000c' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000000d' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000000e' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000000f' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000010' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000011' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000012' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000013' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000014' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000015' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000016' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000017' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000018' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000019' ecx_in='0x00' eax='0xf040f040' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000001a' ecx_in='0x00' eax='0x00000006' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000001b' ecx_in='0x00' eax='0x000003ff' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000001c' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000001d' ecx_in='0x00' eax='0x00004121' ebx='0x01c0003f' ecx='0x0000003f' edx='0x00000000'/>
++  <cpuid eax_in='0x8000001d' ecx_in='0x01' eax='0x00004122' ebx='0x01c0003f' ecx='0x0000003f' edx='0x00000000'/>
++  <cpuid eax_in='0x8000001d' ecx_in='0x02' eax='0x00004143' ebx='0x01c0003f' ecx='0x000003ff' edx='0x00000002'/>
++  <cpuid eax_in='0x8000001d' ecx_in='0x03' eax='0x0001c163' ebx='0x03c0003f' ecx='0x00003fff' edx='0x00000001'/>
++  <cpuid eax_in='0x8000001e' ecx_in='0x00' eax='0x00000031' ebx='0x00000118' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000001f' ecx_in='0x00' eax='0x0001000f' ebx='0x0000016f' ecx='0x000001fd' edx='0x00000001'/>
++  <cpuid eax_in='0x80000020' ecx_in='0x00' eax='0x00000000' ebx='0x00000002' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000020' ecx_in='0x01' eax='0x0000000b' ebx='0x00000000' ecx='0x00000000' edx='0x0000000f'/>
++  <cpuid eax_in='0x80860000' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0xc0000000' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <msr index='0x10a' edx='0x00000000' eax='0x00000069'/>
++</cpudata>
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-Allow-NUMA-nodes-without-vCPUs.patch b/SOURCES/libvirt-Allow-NUMA-nodes-without-vCPUs.patch
new file mode 100644
index 0000000..37df946
--- /dev/null
+++ b/SOURCES/libvirt-Allow-NUMA-nodes-without-vCPUs.patch
@@ -0,0 +1,456 @@
+From 5f6723e71e3765d1d43bfa9ba1c66e0e05e11a48 Mon Sep 17 00:00:00 2001
+Message-Id: <5f6723e71e3765d1d43bfa9ba1c66e0e05e11a48@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Mon, 9 Nov 2020 17:22:32 +0100
+Subject: [PATCH] Allow NUMA nodes without vCPUs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+QEMU allows creating NUMA nodes that have memory only.
+These are somehow important for HMAT.
+
+With check done in qemuValidateDomainDef() for QEMU 2.7 or newer
+(checked via QEMU_CAPS_NUMA), we can be sure that the vCPUs are
+fully assigned to NUMA nodes in domain XML.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit a26f61ee0cffa421b87ef568002b684dd8025432)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Conflicts:
+- src/qemu/qemu_validate.c: This file doesn't exist in downstream
+yet, so I've moved the change that original patch would do to
+qemu_domain.c where the validator lives.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <365508c75e579e9037ad555d6c372068ccd50c95.1604938867.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/formatdomain.html.in                     |  2 +
+ docs/schemas/cputypes.rng                     |  8 ++-
+ src/conf/numa_conf.c                          | 59 ++++++++++---------
+ src/libxl/xen_xl.c                            | 10 ++--
+ src/qemu/qemu_command.c                       | 26 ++++----
+ src/qemu/qemu_domain.c                        | 22 +++----
+ tests/qemuxml2argvdata/numatune-no-vcpu.args  | 33 +++++++++++
+ tests/qemuxml2argvdata/numatune-no-vcpu.xml   | 42 +++++++++++++
+ tests/qemuxml2argvtest.c                      |  1 +
+ tests/qemuxml2xmloutdata/numatune-no-vcpu.xml |  1 +
+ tests/qemuxml2xmltest.c                       |  1 +
+ 11 files changed, 149 insertions(+), 56 deletions(-)
+ create mode 100644 tests/qemuxml2argvdata/numatune-no-vcpu.args
+ create mode 100644 tests/qemuxml2argvdata/numatune-no-vcpu.xml
+ create mode 120000 tests/qemuxml2xmloutdata/numatune-no-vcpu.xml
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 76799f5ffc..4b8d312596 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -1783,6 +1783,8 @@
+       <code>cpus</code> specifies the CPU or range of CPUs that are
+       part of the node. <code>memory</code> specifies the node memory
+       in kibibytes (i.e. blocks of 1024 bytes).
++      <span class="since">Since 6.6.0</span> the <code>cpus</code> attribute
++      is optional and if omitted a CPU-less NUMA node is created.
+       <span class="since">Since 1.2.11</span> one can use an additional <a
+           href="#elementsMemoryAllocation"><code>unit</code></a> attribute to
+       define units in which <code>memory</code> is specified.
+diff --git a/docs/schemas/cputypes.rng b/docs/schemas/cputypes.rng
+index e2744acad3..a1682a1003 100644
+--- a/docs/schemas/cputypes.rng
++++ b/docs/schemas/cputypes.rng
+@@ -115,9 +115,11 @@
+           <ref name="unsignedInt"/>
+         </attribute>
+       </optional>
+-      <attribute name="cpus">
+-        <ref name="cpuset"/>
+-      </attribute>
++      <optional>
++        <attribute name="cpus">
++          <ref name="cpuset"/>
++        </attribute>
++      </optional>
+       <attribute name="memory">
+         <ref name="memoryKB"/>
+       </attribute>
+diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c
+index c9cc8ac22e..a805336d16 100644
+--- a/src/conf/numa_conf.c
++++ b/src/conf/numa_conf.c
+@@ -889,32 +889,28 @@ virDomainNumaDefParseXML(virDomainNumaPtr def,
+         }
+         VIR_FREE(tmp);
+ 
+-        if (def->mem_nodes[cur_cell].cpumask) {
++        if (def->mem_nodes[cur_cell].mem) {
+             virReportError(VIR_ERR_XML_ERROR,
+                            _("Duplicate NUMA cell info for cell id '%u'"),
+                            cur_cell);
+             goto cleanup;
+         }
+ 
+-        if (!(tmp = virXMLPropString(nodes[i], "cpus"))) {
+-            virReportError(VIR_ERR_XML_ERROR, "%s",
+-                           _("Missing 'cpus' attribute in NUMA cell"));
+-            goto cleanup;
+-        }
++        if ((tmp = virXMLPropString(nodes[i], "cpus"))) {
++            g_autoptr(virBitmap) cpumask = NULL;
+ 
+-        if (virBitmapParse(tmp, &def->mem_nodes[cur_cell].cpumask,
+-                           VIR_DOMAIN_CPUMASK_LEN) < 0)
+-            goto cleanup;
++            if (virBitmapParse(tmp, &cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0)
++                goto cleanup;
+ 
+-        if (virBitmapIsAllClear(def->mem_nodes[cur_cell].cpumask)) {
+-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+-                          _("NUMA cell %d has no vCPUs assigned"), cur_cell);
+-            goto cleanup;
++            if (!virBitmapIsAllClear(cpumask))
++                def->mem_nodes[cur_cell].cpumask = g_steal_pointer(&cpumask);
++            VIR_FREE(tmp);
+         }
+-        VIR_FREE(tmp);
+ 
+         for (j = 0; j < n; j++) {
+-            if (j == cur_cell || !def->mem_nodes[j].cpumask)
++            if (j == cur_cell ||
++                !def->mem_nodes[j].cpumask ||
++                !def->mem_nodes[cur_cell].cpumask)
+                 continue;
+ 
+             if (virBitmapOverlaps(def->mem_nodes[j].cpumask,
+@@ -976,7 +972,6 @@ virDomainNumaDefFormatXML(virBufferPtr buf,
+ {
+     virDomainMemoryAccess memAccess;
+     virTristateBool discard;
+-    char *cpustr;
+     size_t ncells = virDomainNumaGetNodeCount(def);
+     size_t i;
+ 
+@@ -986,17 +981,22 @@ virDomainNumaDefFormatXML(virBufferPtr buf,
+     virBufferAddLit(buf, "<numa>\n");
+     virBufferAdjustIndent(buf, 2);
+     for (i = 0; i < ncells; i++) {
++        virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(def, i);
+         int ndistances;
+ 
+         memAccess = virDomainNumaGetNodeMemoryAccessMode(def, i);
+         discard = virDomainNumaGetNodeDiscard(def, i);
+ 
+-        if (!(cpustr = virBitmapFormat(virDomainNumaGetNodeCpumask(def, i))))
+-            return -1;
+-
+         virBufferAddLit(buf, "<cell");
+         virBufferAsprintf(buf, " id='%zu'", i);
+-        virBufferAsprintf(buf, " cpus='%s'", cpustr);
++
++        if (cpumask) {
++            g_autofree char *cpustr = virBitmapFormat(cpumask);
++
++            if (!cpustr)
++                return -1;
++            virBufferAsprintf(buf, " cpus='%s'", cpustr);
++        }
+         virBufferAsprintf(buf, " memory='%llu'",
+                           virDomainNumaGetNodeMemorySize(def, i));
+         virBufferAddLit(buf, " unit='KiB'");
+@@ -1032,8 +1032,6 @@ virDomainNumaDefFormatXML(virBufferPtr buf,
+             virBufferAdjustIndent(buf, -2);
+             virBufferAddLit(buf, "</cell>\n");
+         }
+-
+-        VIR_FREE(cpustr);
+     }
+     virBufferAdjustIndent(buf, -2);
+     virBufferAddLit(buf, "</numa>\n");
+@@ -1048,8 +1046,12 @@ virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa)
+     size_t i;
+     unsigned int ret = 0;
+ 
+-    for (i = 0; i < numa->nmem_nodes; i++)
+-        ret += virBitmapCountBits(virDomainNumaGetNodeCpumask(numa, i));
++    for (i = 0; i < numa->nmem_nodes; i++) {
++        virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(numa, i);
++
++        if (cpumask)
++            ret += virBitmapCountBits(cpumask);
++    }
+ 
+     return ret;
+ }
+@@ -1061,11 +1063,14 @@ virDomainNumaGetMaxCPUID(virDomainNumaPtr numa)
+     unsigned int ret = 0;
+ 
+     for (i = 0; i < numa->nmem_nodes; i++) {
++        virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(numa, i);
+         int bit;
+ 
+-        bit = virBitmapLastSetBit(virDomainNumaGetNodeCpumask(numa, i));
+-        if (bit > ret)
+-            ret = bit;
++        if (cpumask) {
++            bit = virBitmapLastSetBit(cpumask);
++            if (bit > ret)
++                ret = bit;
++        }
+     }
+ 
+     return ret;
+diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c
+index edea30a86a..752fa925ec 100644
+--- a/src/libxl/xen_xl.c
++++ b/src/libxl/xen_xl.c
+@@ -1443,19 +1443,21 @@ xenFormatXLVnuma(virConfValuePtr list,
+ {
+     int ret = -1;
+     size_t i;
+-
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+     virConfValuePtr numaVnode, tmp;
+-
++    virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(numa, node);
+     size_t nodeSize = virDomainNumaGetNodeMemorySize(numa, node) / 1024;
+-    char *nodeVcpus = virBitmapFormat(virDomainNumaGetNodeCpumask(numa, node));
++    g_autofree char *nodeVcpus = NULL;
+ 
+-    if (VIR_ALLOC(numaVnode) < 0)
++    if (!cpumask ||
++        VIR_ALLOC(numaVnode) < 0)
+         goto cleanup;
+ 
+     numaVnode->type = VIR_CONF_LIST;
+     numaVnode->list = NULL;
+ 
++    nodeVcpus = virBitmapFormat(cpumask);
++
+     /* pnode */
+     virBufferAsprintf(&buf, "pnode=%zu", node);
+     xenFormatXLVnode(numaVnode, &buf);
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index 1a573c2817..ac63d18a42 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -7364,8 +7364,6 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg,
+     size_t i, j;
+     virQEMUCapsPtr qemuCaps = priv->qemuCaps;
+     g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+-    char *cpumask = NULL;
+-    char *tmpmask = NULL;
+     char *next = NULL;
+     virBufferPtr nodeBackends = NULL;
+     bool needBackend = false;
+@@ -7400,9 +7398,7 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg,
+         goto cleanup;
+ 
+     for (i = 0; i < ncells; i++) {
+-        VIR_FREE(cpumask);
+-        if (!(cpumask = virBitmapFormat(virDomainNumaGetNodeCpumask(def->numa, i))))
+-            goto cleanup;
++        virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(def->numa, i);
+ 
+         if (needBackend) {
+             virCommandAddArg(cmd, "-object");
+@@ -7412,11 +7408,19 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg,
+         virCommandAddArg(cmd, "-numa");
+         virBufferAsprintf(&buf, "node,nodeid=%zu", i);
+ 
+-        for (tmpmask = cpumask; tmpmask; tmpmask = next) {
+-            if ((next = strchr(tmpmask, ',')))
+-                *(next++) = '\0';
+-            virBufferAddLit(&buf, ",cpus=");
+-            virBufferAdd(&buf, tmpmask, -1);
++        if (cpumask) {
++            g_autofree char *cpumaskStr = NULL;
++            char *tmpmask;
++
++            if (!(cpumaskStr = virBitmapFormat(cpumask)))
++                goto cleanup;
++
++            for (tmpmask = cpumaskStr; tmpmask; tmpmask = next) {
++                if ((next = strchr(tmpmask, ',')))
++                    *(next++) = '\0';
++                virBufferAddLit(&buf, ",cpus=");
++                virBufferAdd(&buf, tmpmask, -1);
++            }
+         }
+ 
+         if (needBackend)
+@@ -7447,8 +7451,6 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg,
+     ret = 0;
+ 
+  cleanup:
+-    VIR_FREE(cpumask);
+-
+     if (nodeBackends) {
+         for (i = 0; i < ncells; i++)
+             virBufferFreeAndReset(&nodeBackends[i]);
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 35b536868a..be25790f12 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -5373,7 +5373,7 @@ qemuDomainDefValidateNuma(const virDomainDef *def,
+     }
+ 
+     for (i = 0; i < ncells; i++) {
+-        g_autofree char * cpumask = NULL;
++        virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(def->numa, i);
+ 
+         if (!hasMemoryCap &&
+             virDomainNumaGetNodeMemoryAccessMode(def->numa, i)) {
+@@ -5383,17 +5383,19 @@ qemuDomainDefValidateNuma(const virDomainDef *def,
+             return -1;
+         }
+ 
+-        if (!(cpumask = virBitmapFormat(virDomainNumaGetNodeCpumask(def->numa, i))))
+-            return -1;
++        if (cpumask) {
++            g_autofree char * cpumaskStr = NULL;
++            if (!(cpumaskStr = virBitmapFormat(cpumask)))
++                return -1;
+ 
+-        if (strchr(cpumask, ',') &&
+-            !virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA)) {
+-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+-                           _("disjoint NUMA cpu ranges are not supported "
+-                             "with this QEMU"));
+-            return -1;
++            if (strchr(cpumaskStr, ',') &&
++                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA)) {
++                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                               _("disjoint NUMA cpu ranges are not supported "
++                                 "with this QEMU"));
++                return -1;
++            }
+         }
+-
+     }
+ 
+     if (virDomainNumaNodesDistancesAreBeingSet(def->numa) &&
+diff --git a/tests/qemuxml2argvdata/numatune-no-vcpu.args b/tests/qemuxml2argvdata/numatune-no-vcpu.args
+new file mode 100644
+index 0000000000..a1f1ee044e
+--- /dev/null
++++ b/tests/qemuxml2argvdata/numatune-no-vcpu.args
+@@ -0,0 +1,33 @@
++LC_ALL=C \
++PATH=/bin \
++HOME=/tmp/lib/domain--1-QEMUGuest \
++USER=test \
++LOGNAME=test \
++XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest/.local/share \
++XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest/.cache \
++XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest/.config \
++QEMU_AUDIO_DRV=none \
++/usr/bin/qemu-system-x86_64 \
++-name QEMUGuest \
++-S \
++-machine pc,accel=tcg,usb=off,dump-guest-core=off \
++-m 12288 \
++-realtime mlock=off \
++-smp 12,sockets=12,cores=1,threads=1 \
++-numa node,nodeid=0,cpus=0-3,mem=2048 \
++-numa node,nodeid=1,cpus=4-7,mem=2048 \
++-numa node,nodeid=2,cpus=8-11,mem=2048 \
++-numa node,nodeid=3,mem=2048 \
++-numa node,nodeid=4,mem=2048 \
++-numa node,nodeid=5,mem=2048 \
++-uuid c7a5fdb2-cdaf-9455-926a-d65c16db1809 \
++-display none \
++-no-user-config \
++-nodefaults \
++-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest/monitor.sock,\
++server,nowait \
++-mon chardev=charmonitor,id=monitor,mode=control \
++-rtc base=utc \
++-no-shutdown \
++-usb \
++-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
+diff --git a/tests/qemuxml2argvdata/numatune-no-vcpu.xml b/tests/qemuxml2argvdata/numatune-no-vcpu.xml
+new file mode 100644
+index 0000000000..f25a07d7ed
+--- /dev/null
++++ b/tests/qemuxml2argvdata/numatune-no-vcpu.xml
+@@ -0,0 +1,42 @@
++<domain type='qemu'>
++  <name>QEMUGuest</name>
++  <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>12582912</memory>
++  <currentMemory unit='KiB'>12582912</currentMemory>
++  <vcpu placement='static'>12</vcpu>
++  <os>
++    <type arch='x86_64' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <features>
++    <acpi/>
++    <apic/>
++    <pae/>
++  </features>
++  <cpu>
++    <numa>
++      <cell id='0' cpus='0-3' memory='2097152' unit='KiB'/>
++      <cell id='1' cpus='4-7' memory='2097152' unit='KiB'/>
++      <cell id='2' cpus='8-11' memory='2097152' unit='KiB'/>
++      <cell id='3' memory='2097152' unit='KiB'/>
++      <cell id='4' memory='2097152' unit='KiB'/>
++      <cell id='5' memory='2097152' unit='KiB'/>
++    </numa>
++  </cpu>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>restart</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-x86_64</emulator>
++    <controller type='usb' index='0'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
++    </controller>
++    <controller type='pci' index='0' model='pci-root'/>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <memballoon model='virtio'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
++    </memballoon>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
+index ff92af606d..49699e495d 100644
+--- a/tests/qemuxml2argvtest.c
++++ b/tests/qemuxml2argvtest.c
+@@ -1812,6 +1812,7 @@ mymain(void)
+     DO_TEST_PARSE_ERROR("numatune-memnode-no-memory", NONE);
+ 
+     DO_TEST("numatune-distances", QEMU_CAPS_NUMA, QEMU_CAPS_NUMA_DIST);
++    DO_TEST("numatune-no-vcpu", NONE);
+ 
+     DO_TEST("numatune-auto-nodeset-invalid", NONE);
+     DO_TEST("numatune-auto-prefer", QEMU_CAPS_OBJECT_MEMORY_RAM,
+diff --git a/tests/qemuxml2xmloutdata/numatune-no-vcpu.xml b/tests/qemuxml2xmloutdata/numatune-no-vcpu.xml
+new file mode 120000
+index 0000000000..f213032685
+--- /dev/null
++++ b/tests/qemuxml2xmloutdata/numatune-no-vcpu.xml
+@@ -0,0 +1 @@
++../qemuxml2argvdata/numatune-no-vcpu.xml
+\ No newline at end of file
+diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
+index 6c3f5c4a9e..1ddeba30f0 100644
+--- a/tests/qemuxml2xmltest.c
++++ b/tests/qemuxml2xmltest.c
+@@ -1105,6 +1105,7 @@ mymain(void)
+     DO_TEST("numatune-memnode", QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_FILE);
+     DO_TEST("numatune-memnode-no-memory", QEMU_CAPS_OBJECT_MEMORY_FILE);
+     DO_TEST("numatune-distances", QEMU_CAPS_NUMA, QEMU_CAPS_NUMA_DIST);
++    DO_TEST("numatune-no-vcpu", QEMU_CAPS_NUMA);
+ 
+     DO_TEST("bios-nvram", NONE);
+     DO_TEST("bios-nvram-os-interleave", NONE);
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-RNG-Allow-interleaving-of-domain-cpu-numa-cell-children.patch b/SOURCES/libvirt-RNG-Allow-interleaving-of-domain-cpu-numa-cell-children.patch
new file mode 100644
index 0000000..27fb4b4
--- /dev/null
+++ b/SOURCES/libvirt-RNG-Allow-interleaving-of-domain-cpu-numa-cell-children.patch
@@ -0,0 +1,63 @@
+From e37b1531942872a229b9f45524ea4679f3b1e8d6 Mon Sep 17 00:00:00 2001
+Message-Id: <e37b1531942872a229b9f45524ea4679f3b1e8d6@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Mon, 9 Nov 2020 17:22:33 +0100
+Subject: [PATCH] RNG: Allow interleaving of /domain/cpu/numa/cell children
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+So far, the <cell/> element can have two types of children
+elements: <distances/> and <cache/> (which can be repeated more
+times). However, there is no reason to require specific order in
+input XML. Allow elements to be interleaved.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit fd2ad818b29ca56904dd228f0774f553f99c1157)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <48b8e99ea6fbc6bcab0f7b3d17e7824ef1b232e2.1604938847.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/schemas/cputypes.rng | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+diff --git a/docs/schemas/cputypes.rng b/docs/schemas/cputypes.rng
+index ba30dbf9ff..a1cae23161 100644
+--- a/docs/schemas/cputypes.rng
++++ b/docs/schemas/cputypes.rng
+@@ -146,16 +146,18 @@
+           <ref name="virYesNo"/>
+         </attribute>
+       </optional>
+-      <optional>
+-        <element name="distances">
+-          <oneOrMore>
+-            <ref name="numaDistance"/>
+-          </oneOrMore>
+-        </element>
+-      </optional>
+-      <zeroOrMore>
+-        <ref name="numaCache"/>
+-      </zeroOrMore>
++      <interleave>
++        <optional>
++          <element name="distances">
++            <oneOrMore>
++              <ref name="numaDistance"/>
++            </oneOrMore>
++          </element>
++        </optional>
++        <zeroOrMore>
++          <ref name="numaCache"/>
++        </zeroOrMore>
++      </interleave>
+     </element>
+   </define>
+ 
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-cgroup-use-virCgroupSetCpuShares-instead-of-virCgroupSetupCpuShares.patch b/SOURCES/libvirt-cgroup-use-virCgroupSetCpuShares-instead-of-virCgroupSetupCpuShares.patch
new file mode 100644
index 0000000..9eec89b
--- /dev/null
+++ b/SOURCES/libvirt-cgroup-use-virCgroupSetCpuShares-instead-of-virCgroupSetupCpuShares.patch
@@ -0,0 +1,146 @@
+From 8d08db00d403ddd17cb51d972842c6d13a122d57 Mon Sep 17 00:00:00 2001
+Message-Id: <8d08db00d403ddd17cb51d972842c6d13a122d57@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Thu, 4 Mar 2021 12:57:58 +0100
+Subject: [PATCH] cgroup: use virCgroupSetCpuShares instead of
+ virCgroupSetupCpuShares
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Now that we enforce the cpu.shares range kernel will no longer silently
+change the value that libvirt configures so there is no need to read
+the value back to get the actual configuration.
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit e95489d813cb7cc68b02905ce3ec059bc395b465)
+
+Conflicts:
+    src/lxc/lxc_cgroup.c
+    src/lxc/lxc_driver.c
+    src/qemu/qemu_cgroup.c
+    src/qemu/qemu_driver.c
+        - downstream doesn't have virCgroupSetupCpuShares() function
+          so we just remove usage of virCgroupGetCpuShares()
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <a7f8e3c0ce4bc22eccbaa25a434d5e72e74d8a65.1614858616.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/lxc/lxc_cgroup.c   |  5 -----
+ src/lxc/lxc_driver.c   |  6 +-----
+ src/qemu/qemu_cgroup.c | 20 --------------------
+ src/qemu/qemu_driver.c |  8 ++------
+ 4 files changed, 3 insertions(+), 36 deletions(-)
+
+diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
+index 7f3701593a..f785f50754 100644
+--- a/src/lxc/lxc_cgroup.c
++++ b/src/lxc/lxc_cgroup.c
+@@ -38,13 +38,8 @@ static int virLXCCgroupSetupCpuTune(virDomainDefPtr def,
+                                     virCgroupPtr cgroup)
+ {
+     if (def->cputune.sharesSpecified) {
+-        unsigned long long val;
+         if (virCgroupSetCpuShares(cgroup, def->cputune.shares) < 0)
+             return -1;
+-
+-        if (virCgroupGetCpuShares(cgroup, &val) < 0)
+-            return -1;
+-        def->cputune.shares = val;
+     }
+ 
+     if (def->cputune.quota != 0 &&
+diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
+index a8c93dd228..853ddac8b9 100644
+--- a/src/lxc/lxc_driver.c
++++ b/src/lxc/lxc_driver.c
+@@ -1909,14 +1909,10 @@ lxcDomainSetSchedulerParametersFlags(virDomainPtr dom,
+ 
+         if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_CPU_SHARES)) {
+             if (def) {
+-                unsigned long long val;
+                 if (virCgroupSetCpuShares(priv->cgroup, params[i].value.ul) < 0)
+                     goto endjob;
+ 
+-                if (virCgroupGetCpuShares(priv->cgroup, &val) < 0)
+-                    goto endjob;
+-
+-                def->cputune.shares = val;
++                def->cputune.shares = params[i].value.ul;
+                 def->cputune.sharesSpecified = true;
+             }
+ 
+diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
+index 3a62b4ac15..95ea5bed74 100644
+--- a/src/qemu/qemu_cgroup.c
++++ b/src/qemu/qemu_cgroup.c
+@@ -933,10 +933,6 @@ static int
+ qemuSetupCpuCgroup(virDomainObjPtr vm)
+ {
+     qemuDomainObjPrivatePtr priv = vm->privateData;
+-    virObjectEventPtr event = NULL;
+-    virTypedParameterPtr eventParams = NULL;
+-    int eventNparams = 0;
+-    int eventMaxparams = 0;
+ 
+     if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
+        if (vm->def->cputune.sharesSpecified) {
+@@ -949,24 +945,8 @@ qemuSetupCpuCgroup(virDomainObjPtr vm)
+     }
+ 
+     if (vm->def->cputune.sharesSpecified) {
+-        unsigned long long val;
+         if (virCgroupSetCpuShares(priv->cgroup, vm->def->cputune.shares) < 0)
+             return -1;
+-
+-        if (virCgroupGetCpuShares(priv->cgroup, &val) < 0)
+-            return -1;
+-        if (vm->def->cputune.shares != val) {
+-            vm->def->cputune.shares = val;
+-            if (virTypedParamsAddULLong(&eventParams, &eventNparams,
+-                                        &eventMaxparams,
+-                                        VIR_DOMAIN_TUNABLE_CPU_CPU_SHARES,
+-                                        val) < 0)
+-                return -1;
+-
+-            event = virDomainEventTunableNewFromObj(vm, eventParams, eventNparams);
+-        }
+-
+-        virObjectEventStateQueue(priv->driver->domainEventState, event);
+     }
+ 
+     return 0;
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index a1103a96dd..3914d3ff68 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -10625,20 +10625,16 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom,
+ 
+         if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_CPU_SHARES)) {
+             if (def) {
+-                unsigned long long val;
+                 if (virCgroupSetCpuShares(priv->cgroup, value_ul) < 0)
+                     goto endjob;
+ 
+-                if (virCgroupGetCpuShares(priv->cgroup, &val) < 0)
+-                    goto endjob;
+-
+-                def->cputune.shares = val;
++                def->cputune.shares = value_ul;
+                 def->cputune.sharesSpecified = true;
+ 
+                 if (virTypedParamsAddULLong(&eventParams, &eventNparams,
+                                             &eventMaxNparams,
+                                             VIR_DOMAIN_TUNABLE_CPU_CPU_SHARES,
+-                                            val) < 0)
++                                            value_ul) < 0)
+                     goto endjob;
+             }
+ 
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-check-for-NULL-before-calling-g_regex_unref.patch b/SOURCES/libvirt-check-for-NULL-before-calling-g_regex_unref.patch
new file mode 100644
index 0000000..a0c6d04
--- /dev/null
+++ b/SOURCES/libvirt-check-for-NULL-before-calling-g_regex_unref.patch
@@ -0,0 +1,77 @@
+From 5fe7795d5fa5061f0ba615472f9351f9d29abf48 Mon Sep 17 00:00:00 2001
+Message-Id: <5fe7795d5fa5061f0ba615472f9351f9d29abf48@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Fri, 2 Oct 2020 13:44:44 +0200
+Subject: [PATCH] check for NULL before calling g_regex_unref
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+g_regex_unref reports an error if called with a NULL argument.
+
+We have two cases in the code where we (possibly) call it on a NULL
+argument. The interesting one is in virDomainQemuMonitorEventCleanup.
+
+Based on VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX, we unref
+data->regex, which has two problems:
+
+* On the client side, flags is -1 so the comparison is true even if no
+  regex was used, reproducible by:
+  $ virsh qemu-monitor-event --timeout 1
+  which results in an ugly error:
+(process:1289846): GLib-CRITICAL **: 14:58:42.631: g_regex_unref: assertion 'regex != NULL' failed
+* On the server side, we only create the regex if both the flag and the
+  string are present, so it's possible to trigger this message by:
+  $ virsh qemu-monitor-event --regex --timeout 1
+
+Use a non-NULL comparison instead of the flag to decide whether we need
+to unref the regex. And add a non-NULL check to the unref in the
+VirtualBox test too.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Fixes: 71efb59a4de7c51b1bc889a316f1796ebf55738f
+https://bugzilla.redhat.com/show_bug.cgi?id=1876907
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
+(cherry picked from commit 92b252456ee6d6ffc6e39e62ce1ce6c50113e00e)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1861176
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Message-Id: <7d3c84f6556d0d46ada037d5e56c831babba609f.1601639064.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/conf/domain_event.c     | 2 +-
+ tests/vboxsnapshotxmltest.c | 3 ++-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
+index 33fbf10406..d3acde0236 100644
+--- a/src/conf/domain_event.c
++++ b/src/conf/domain_event.c
+@@ -2194,7 +2194,7 @@ virDomainQemuMonitorEventCleanup(void *opaque)
+     virDomainQemuMonitorEventData *data = opaque;
+ 
+     VIR_FREE(data->event);
+-    if (data->flags & VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX)
++    if (data->regex)
+         g_regex_unref(data->regex);
+     if (data->freecb)
+         (data->freecb)(data->opaque);
+diff --git a/tests/vboxsnapshotxmltest.c b/tests/vboxsnapshotxmltest.c
+index d1a7522931..8577157020 100644
+--- a/tests/vboxsnapshotxmltest.c
++++ b/tests/vboxsnapshotxmltest.c
+@@ -134,7 +134,8 @@ mymain(void)
+     DO_TEST("2disks-3snap-brother");
+ 
+  cleanup:
+-    g_regex_unref(testSnapshotXMLVariableLineRegex);
++    if (testSnapshotXMLVariableLineRegex)
++        g_regex_unref(testSnapshotXMLVariableLineRegex);
+     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+ 
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-conf-Move-and-rename-virDomainParseScaledValue.patch b/SOURCES/libvirt-conf-Move-and-rename-virDomainParseScaledValue.patch
new file mode 100644
index 0000000..52e7f0b
--- /dev/null
+++ b/SOURCES/libvirt-conf-Move-and-rename-virDomainParseScaledValue.patch
@@ -0,0 +1,357 @@
+From 0cee78aa69f5e3317b5e4853454a108e597228e5 Mon Sep 17 00:00:00 2001
+Message-Id: <0cee78aa69f5e3317b5e4853454a108e597228e5@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 7 Oct 2020 18:45:33 +0200
+Subject: [PATCH] conf: Move and rename virDomainParseScaledValue()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There is nothing domain specific about the function, thus it
+should not have virDomain prefix. Also, the fact that it is a
+static function makes it impossible to use from other files.
+Move the function to virxml.c and drop the 'Domain' infix.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 04bd77a19f8312493151ce377da40577b1470a0b)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Conflicts:
+- src/conf/domain_conf.c: Some context mismatch, and some areas
+the original commit changes don't exist in this old libvirt yet
+or the calls are in other places because of refactors.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <26a847deef5941fd90f892cf5fe1443cf3fc90ca.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c   | 135 ++++++++++-----------------------------
+ src/libvirt_private.syms |   1 +
+ src/util/virxml.c        |  72 +++++++++++++++++++++
+ src/util/virxml.h        |   8 +++
+ 4 files changed, 114 insertions(+), 102 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 306926b64c..484f3b4352 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -10644,75 +10644,6 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
+     goto cleanup;
+ }
+ 
+-/**
+- * virDomainParseScaledValue:
+- * @xpath: XPath to memory amount
+- * @units_xpath: XPath to units attribute
+- * @ctxt: XPath context
+- * @val: scaled value is stored here
+- * @scale: default scale for @val
+- * @max: maximal @val allowed
+- * @required: is the value required?
+- *
+- * Parse a value located at @xpath within @ctxt, and store the
+- * result into @val. The value is scaled by units located at
+- * @units_xpath (or the 'unit' attribute under @xpath if
+- * @units_xpath is NULL). If units are not present, the default
+- * @scale is used. If @required is set, then the value must
+- * exist; otherwise, the value is optional. The resulting value
+- * is in bytes.
+- *
+- * Returns 1 on success,
+- *         0 if the value was not present and !@required,
+- *         -1 on failure after issuing error.
+- */
+-static int
+-virDomainParseScaledValue(const char *xpath,
+-                          const char *units_xpath,
+-                          xmlXPathContextPtr ctxt,
+-                          unsigned long long *val,
+-                          unsigned long long scale,
+-                          unsigned long long max,
+-                          bool required)
+-{
+-    unsigned long long bytes;
+-    g_autofree char *xpath_full = NULL;
+-    g_autofree char *unit = NULL;
+-    g_autofree char *bytes_str = NULL;
+-
+-    *val = 0;
+-    xpath_full = g_strdup_printf("string(%s)", xpath);
+-
+-    bytes_str = virXPathString(xpath_full, ctxt);
+-    if (!bytes_str) {
+-        if (!required)
+-            return 0;
+-        virReportError(VIR_ERR_XML_ERROR,
+-                       _("missing element or attribute '%s'"),
+-                       xpath);
+-        return -1;
+-    }
+-    VIR_FREE(xpath_full);
+-
+-    if (virStrToLong_ullp(bytes_str, NULL, 10, &bytes) < 0) {
+-        virReportError(VIR_ERR_XML_ERROR,
+-                       _("Invalid value '%s' for element or attribute '%s'"),
+-                       bytes_str, xpath);
+-        return -1;
+-    }
+-
+-    if (units_xpath)
+-         xpath_full = g_strdup_printf("string(%s)", units_xpath);
+-    else
+-         xpath_full = g_strdup_printf("string(%s/@unit)", xpath);
+-    unit = virXPathString(xpath_full, ctxt);
+-
+-    if (virScaleInteger(&bytes, unit, scale, max) < 0)
+-        return -1;
+-
+-    *val = bytes;
+-    return 1;
+-}
+ 
+ 
+ /**
+@@ -10749,8 +10680,8 @@ virDomainParseMemory(const char *xpath,
+ 
+     max = virMemoryMaxValue(capped);
+ 
+-    if (virDomainParseScaledValue(xpath, units_xpath, ctxt,
+-                                  &bytes, 1024, max, required) < 0)
++    if (virParseScaledValue(xpath, units_xpath, ctxt,
++                            &bytes, 1024, max, required) < 0)
+         return -1;
+ 
+     /* Yes, we really do use kibibytes for our internal sizing.  */
+@@ -10792,9 +10723,9 @@ virDomainParseMemoryLimit(const char *xpath,
+     int ret;
+     unsigned long long bytes;
+ 
+-    ret = virDomainParseScaledValue(xpath, units_xpath, ctxt, &bytes, 1024,
+-                                    VIR_DOMAIN_MEMORY_PARAM_UNLIMITED << 10,
+-                                    false);
++    ret = virParseScaledValue(xpath, units_xpath, ctxt, &bytes, 1024,
++                              VIR_DOMAIN_MEMORY_PARAM_UNLIMITED << 10,
++                              false);
+ 
+     if (ret < 0)
+         return -1;
+@@ -11125,9 +11056,9 @@ virDomainControllerDefParseXML(virDomainXMLOptionPtr xmlopt,
+                                  "have an address"));
+                 goto error;
+             }
+-            if ((rc = virDomainParseScaledValue("./pcihole64", NULL,
+-                                                ctxt, &bytes, 1024,
+-                                                1024ULL * ULONG_MAX, false)) < 0)
++            if ((rc = virParseScaledValue("./pcihole64", NULL,
++                                          ctxt, &bytes, 1024,
++                                          1024ULL * ULONG_MAX, false)) < 0)
+                 goto error;
+ 
+             if (rc == 1)
+@@ -11349,14 +11280,14 @@ virDomainFSDefParseXML(virDomainXMLOptionPtr xmlopt,
+         }
+     }
+ 
+-    if (virDomainParseScaledValue("./space_hard_limit[1]",
+-                                  NULL, ctxt, &def->space_hard_limit,
+-                                  1, ULLONG_MAX, false) < 0)
++    if (virParseScaledValue("./space_hard_limit[1]",
++                            NULL, ctxt, &def->space_hard_limit,
++                            1, ULLONG_MAX, false) < 0)
+         goto error;
+ 
+-    if (virDomainParseScaledValue("./space_soft_limit[1]",
+-                                  NULL, ctxt, &def->space_soft_limit,
+-                                  1, ULLONG_MAX, false) < 0)
++    if (virParseScaledValue("./space_soft_limit[1]",
++                            NULL, ctxt, &def->space_soft_limit,
++                            1, ULLONG_MAX, false) < 0)
+         goto error;
+ 
+     cur = node->children;
+@@ -15205,8 +15136,8 @@ virDomainShmemDefParseXML(virDomainXMLOptionPtr xmlopt,
+         goto cleanup;
+     }
+ 
+-    if (virDomainParseScaledValue("./size[1]", NULL, ctxt,
+-                                  &def->size, 1, ULLONG_MAX, false) < 0)
++    if (virParseScaledValue("./size[1]", NULL, ctxt,
++                            &def->size, 1, ULLONG_MAX, false) < 0)
+         goto cleanup;
+ 
+     if ((server = virXPathNode("./server[1]", ctxt))) {
+@@ -19603,9 +19534,9 @@ virDomainCachetuneDefParseCache(xmlXPathContextPtr ctxt,
+         return -1;
+     }
+ 
+-    if (virDomainParseScaledValue("./@size", "./@unit",
+-                                  ctxt, &size, 1024,
+-                                  ULLONG_MAX, true) < 0)
++    if (virParseScaledValue("./@size", "./@unit",
++                            ctxt, &size, 1024,
++                            ULLONG_MAX, true) < 0)
+         return -1;
+ 
+     if (virResctrlAllocSetCacheSize(alloc, level, type, cache, size) < 0)
+@@ -20712,13 +20643,13 @@ virDomainDefParseXML(xmlDocPtr xml,
+                 VIR_FREE(tmp);
+             }
+ 
+-            if (virDomainParseScaledValue("./features/hpt/maxpagesize",
+-                                          NULL,
+-                                          ctxt,
+-                                          &def->hpt_maxpagesize,
+-                                          1024,
+-                                          ULLONG_MAX,
+-                                          false) < 0) {
++            if (virParseScaledValue("./features/hpt/maxpagesize",
++                                    NULL,
++                                    ctxt,
++                                    &def->hpt_maxpagesize,
++                                    1024,
++                                    ULLONG_MAX,
++                                    false) < 0) {
+                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                "%s",
+                                _("Unable to parse HPT maxpagesize setting"));
+@@ -20944,13 +20875,13 @@ virDomainDefParseXML(xmlDocPtr xml,
+     }
+ 
+     if (def->features[VIR_DOMAIN_FEATURE_SMM] == VIR_TRISTATE_SWITCH_ON) {
+-        int rv = virDomainParseScaledValue("string(./features/smm/tseg)",
+-                                           "string(./features/smm/tseg/@unit)",
+-                                           ctxt,
+-                                           &def->tseg_size,
+-                                           1024 * 1024, /* Defaults to mebibytes */
+-                                           ULLONG_MAX,
+-                                           false);
++        int rv = virParseScaledValue("string(./features/smm/tseg)",
++                                     "string(./features/smm/tseg/@unit)",
++                                     ctxt,
++                                     &def->tseg_size,
++                                     1024 * 1024, /* Defaults to mebibytes */
++                                     ULLONG_MAX,
++                                     false);
+         if (rv < 0)
+             goto error;
+         def->tseg_specified = rv;
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 130828706a..acb25eb8c8 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -3442,6 +3442,7 @@ virVsockSetGuestCid;
+ 
+ 
+ # util/virxml.h
++virParseScaledValue;
+ virXMLCheckIllegalChars;
+ virXMLChildElementCount;
+ virXMLExtractNamespaceXML;
+diff --git a/src/util/virxml.c b/src/util/virxml.c
+index 0e66d1623b..bae2e6aca5 100644
+--- a/src/util/virxml.c
++++ b/src/util/virxml.c
+@@ -33,6 +33,7 @@
+ #include "viralloc.h"
+ #include "virfile.h"
+ #include "virstring.h"
++#include "virutil.h"
+ 
+ #define VIR_FROM_THIS VIR_FROM_XML
+ 
+@@ -1433,3 +1434,74 @@ virXMLNamespaceRegister(xmlXPathContextPtr ctxt,
+ 
+     return 0;
+ }
++
++
++/**
++ * virParseScaledValue:
++ * @xpath: XPath to memory amount
++ * @units_xpath: XPath to units attribute
++ * @ctxt: XPath context
++ * @val: scaled value is stored here
++ * @scale: default scale for @val
++ * @max: maximal @val allowed
++ * @required: is the value required?
++ *
++ * Parse a value located at @xpath within @ctxt, and store the
++ * result into @val. The value is scaled by units located at
++ * @units_xpath (or the 'unit' attribute under @xpath if
++ * @units_xpath is NULL). If units are not present, the default
++ * @scale is used. If @required is set, then the value must
++ * exist; otherwise, the value is optional. The resulting value
++ * is in bytes.
++ *
++ * Returns 1 on success,
++ *         0 if the value was not present and !@required,
++ *         -1 on failure after issuing error.
++ */
++int
++virParseScaledValue(const char *xpath,
++                    const char *units_xpath,
++                    xmlXPathContextPtr ctxt,
++                    unsigned long long *val,
++                    unsigned long long scale,
++                    unsigned long long max,
++                    bool required)
++{
++    unsigned long long bytes;
++    g_autofree char *xpath_full = NULL;
++    g_autofree char *unit = NULL;
++    g_autofree char *bytes_str = NULL;
++
++    *val = 0;
++    xpath_full = g_strdup_printf("string(%s)", xpath);
++
++    bytes_str = virXPathString(xpath_full, ctxt);
++    if (!bytes_str) {
++        if (!required)
++            return 0;
++        virReportError(VIR_ERR_XML_ERROR,
++                       _("missing element or attribute '%s'"),
++                       xpath);
++        return -1;
++    }
++    VIR_FREE(xpath_full);
++
++    if (virStrToLong_ullp(bytes_str, NULL, 10, &bytes) < 0) {
++        virReportError(VIR_ERR_XML_ERROR,
++                       _("Invalid value '%s' for element or attribute '%s'"),
++                       bytes_str, xpath);
++        return -1;
++    }
++
++    if (units_xpath)
++         xpath_full = g_strdup_printf("string(%s)", units_xpath);
++    else
++         xpath_full = g_strdup_printf("string(%s/@unit)", xpath);
++    unit = virXPathString(xpath_full, ctxt);
++
++    if (virScaleInteger(&bytes, unit, scale, max) < 0)
++        return -1;
++
++    *val = bytes;
++    return 1;
++}
+diff --git a/src/util/virxml.h b/src/util/virxml.h
+index 26ab9f9c2d..39b261687a 100644
+--- a/src/util/virxml.h
++++ b/src/util/virxml.h
+@@ -269,3 +269,11 @@ virXMLNamespaceFormatNS(virBufferPtr buf,
+ int
+ virXMLNamespaceRegister(xmlXPathContextPtr ctxt,
+                         virXMLNamespace const *ns);
++
++int virParseScaledValue(const char *xpath,
++                        const char *units_xpath,
++                        xmlXPathContextPtr ctxt,
++                        unsigned long long *val,
++                        unsigned long long scale,
++                        unsigned long long max,
++                        bool required);
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-conf-Parse-and-format-HMAT.patch b/SOURCES/libvirt-conf-Parse-and-format-HMAT.patch
new file mode 100644
index 0000000..6f3d8f6
--- /dev/null
+++ b/SOURCES/libvirt-conf-Parse-and-format-HMAT.patch
@@ -0,0 +1,877 @@
+From 17e9b949ec3876e74bcaa217810afbd46f297a65 Mon Sep 17 00:00:00 2001
+Message-Id: <17e9b949ec3876e74bcaa217810afbd46f297a65@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 7 Oct 2020 18:45:39 +0200
+Subject: [PATCH] conf: Parse and format HMAT
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+To cite ACPI specification:
+
+  Heterogeneous Memory Attribute Table describes the memory
+  attributes, such as memory side cache attributes and bandwidth
+  and latency details, related to the System Physical Address
+  (SPA) Memory Ranges. The software is expected to use this
+  information as hint for optimization.
+
+According to our upstream discussion [1] this is exposed under
+<numa/> as <cache/> under NUMA <cell/> and <latency> or
+<bandwidth/> under numa/latencies.
+
+1: https://www.redhat.com/archives/libvir-list/2020-January/msg00422.html
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit a89bbbac86383a10be0cec5a93feb7ed820871eb)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Conflicts:
+- src/conf/numa_conf.c: Context, because we're not using
+VIR_XPATH_NODE_AUTORESTORE() everywhere in the old code.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <f5d9028ca8eff876c2bd471460629d0ef3b20630.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/formatdomain.html.in                  | 107 +++++++
+ docs/schemas/cputypes.rng                  | 110 ++++++-
+ src/conf/numa_conf.c                       | 349 ++++++++++++++++++++-
+ src/conf/numa_conf.h                       |  33 ++
+ src/libvirt_private.syms                   |   6 +
+ tests/qemuxml2argvdata/numatune-hmat.xml   |  52 +++
+ tests/qemuxml2xmloutdata/numatune-hmat.xml |   1 +
+ tests/qemuxml2xmltest.c                    |   1 +
+ 8 files changed, 644 insertions(+), 15 deletions(-)
+ create mode 100644 tests/qemuxml2argvdata/numatune-hmat.xml
+ create mode 120000 tests/qemuxml2xmloutdata/numatune-hmat.xml
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 4b8d312596..bec753e37f 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -1874,6 +1874,113 @@
+       using 10 for local and 20 for remote distances.
+     </p>
+ 
++    <h4><a id="hmat">ACPI Heterogeneous Memory Attribute Table</a></h4>
++
++<pre>
++...
++&lt;cpu&gt;
++  ...
++  &lt;numa&gt;
++    &lt;cell id='0' cpus='0-3' memory='512000' unit='KiB' discard='yes'/&gt;
++    &lt;cell id='1' cpus='4-7' memory='512000' unit='KiB' memAccess='shared'/&gt;
++    &lt;cell id='3' cpus='0-3' memory='2097152' unit='KiB'&gt;
++      &lt;cache level='1' associativity='direct' policy='writeback'&gt;
++        &lt;size value='10' unit='KiB'/&gt;
++        &lt;line value='8' unit='B'/&gt;
++      &lt;/cache&gt;
++    &lt;/cell&gt;
++    &lt;interconnects&gt;
++      &lt;latency initiator='0' target='0' type='access' value='5'/&gt;
++      &lt;latency initiator='0' target='0' cache='1' type='access' value='10'/&gt;
++      &lt;bandwidth initiator='0' target='0' type='access' value='204800' unit='KiB'/&gt;
++    &lt;/interconnects&gt;
++  &lt;/numa&gt;
++  ...
++&lt;/cpu&gt;
++...</pre>
++
++    <p>
++      <span class='since'>Since 6.6.0</span> the <code>cell</code> element can
++      have a <code>cache</code> child element which describes memory side cache
++      for memory proximity domains. The <code>cache</code> element has a
++      <code>level</code> attribute describing the cache level and thus the
++      element can be repeated multiple times to describe different levels of
++      the cache.
++    </p>
++
++    <p>
++      The <code>cache</code> element then has following mandatory attributes:
++    </p>
++
++    <dl>
++      <dt><code>level</code></dt>
++      <dd>
++        Level of the cache this description refers to.
++      </dd>
++
++      <dt><code>associativity</code></dt>
++      <dd>
++        Describes cache associativity (accepted values are <code>none</code>,
++        <code>direct</code> and <code>full</code>).
++      </dd>
++
++      <dt><code>policy</code></dt>
++      <dd>
++        Describes cache write associativity (accepted values are
++        <code>none</code>, <code>writeback</code> and
++        <code>writethrough</code>).
++      </dd>
++    </dl>
++
++    <p>
++      The <code>cache</code> element has two mandatory child elements then:
++      <code>size</code> and <code>line</code> which describe cache size and
++      cache line size. Both elements accept two attributes: <code>value</code>
++      and <code>unit</code> which set the value of corresponding cache
++      attribute.
++    </p>
++
++    <p>
++      The NUMA description has an optional <code>interconnects</code> element that
++      describes the normalized memory read/write latency, read/write bandwidth
++      between Initiator Proximity Domains (Processor or I/O) and Target
++      Proximity Domains (Memory).
++    </p>
++
++    <p>
++      The <code>interconnects</code> element can have zero or more
++      <code>latency</code> child elements to describe latency between two
++      memory nodes and zero or more <code>bandwidth</code> child elements to
++      describe bandwidth between two memory nodes. Both these have the
++      following mandatory attributes:
++    </p>
++
++    <dl>
++      <dt><code>initiator</code></dt>
++      <dd>Refers to the source NUMA node</dd>
++
++      <dt><code>target</code></dt>
++      <dd>Refers to the target NUMA node</dd>
++
++      <dt><code>type</code></dt>
++      <dd>The type of the access. Accepted values: <code>access</code>,
++      <code>read</code>, <code>write</code></dd>
++
++      <dt><code>value</code></dt>
++      <dd>The actual value. For latency this is delay in nanoseconds, for
++      bandwidth this value is in kibibytes per second. Use additional
++      <code>unit</code> attribute to change the units.</dd>
++    </dl>
++
++    <p>
++      To describe latency from one NUMA node to a cache of another NUMA node
++      the <code>latency</code> element has optional <code>cache</code>
++      attribute which in combination with <code>target</code> attribute creates
++      full reference to distant NUMA node's cache level. For instance,
++      <code>target='0' cache='1'</code> refers to the first level cache of NUMA
++      node 0.
++    </p>
++
+     <h3><a id="elementsEvents">Events configuration</a></h3>
+ 
+     <p>
+diff --git a/docs/schemas/cputypes.rng b/docs/schemas/cputypes.rng
+index a1682a1003..ba30dbf9ff 100644
+--- a/docs/schemas/cputypes.rng
++++ b/docs/schemas/cputypes.rng
+@@ -102,9 +102,14 @@
+ 
+   <define name="cpuNuma">
+     <element name="numa">
+-      <oneOrMore>
+-        <ref name="numaCell"/>
+-      </oneOrMore>
++      <interleave>
++        <oneOrMore>
++          <ref name="numaCell"/>
++        </oneOrMore>
++        <optional>
++          <ref name="numaInterconnects"/>
++        </optional>
++      </interleave>
+     </element>
+   </define>
+ 
+@@ -148,6 +153,9 @@
+           </oneOrMore>
+         </element>
+       </optional>
++      <zeroOrMore>
++        <ref name="numaCache"/>
++      </zeroOrMore>
+     </element>
+   </define>
+ 
+@@ -162,6 +170,102 @@
+     </element>
+   </define>
+ 
++  <define name="numaCache">
++    <element name="cache">
++      <attribute name="level">
++        <ref name="unsignedInt"/>
++      </attribute>
++      <attribute name="associativity">
++        <choice>
++          <value>none</value>
++          <value>direct</value>
++          <value>full</value>
++        </choice>
++      </attribute>
++      <attribute name="policy">
++        <choice>
++          <value>none</value>
++          <value>writeback</value>
++          <value>writethrough</value>
++        </choice>
++      </attribute>
++      <interleave>
++        <element name="size">
++          <attribute name="value">
++            <ref name="unsignedInt"/>
++          </attribute>
++          <attribute name="unit">
++            <ref name="unit"/>
++          </attribute>
++        </element>
++        <element name="line">
++          <attribute name="value">
++            <ref name="unsignedInt"/>
++          </attribute>
++          <attribute name="unit">
++            <ref name="unit"/>
++          </attribute>
++        </element>
++      </interleave>
++    </element>
++  </define>
++
++  <define name="numaInterconnects">
++    <element name="interconnects">
++      <interleave>
++        <zeroOrMore>
++          <element name="latency">
++            <attribute name="initiator">
++              <ref name="unsignedInt"/>
++            </attribute>
++            <attribute name="target">
++              <ref name="unsignedInt"/>
++            </attribute>
++            <optional>
++              <attribute name="cache">
++                <ref name="unsignedInt"/>
++              </attribute>
++            </optional>
++            <attribute name="type">
++              <choice>
++                <value>access</value>
++                <value>read</value>
++                <value>write</value>
++              </choice>
++            </attribute>
++            <attribute name="value">
++              <ref name="unsignedInt"/>
++            </attribute>
++            <empty/>
++          </element>
++        </zeroOrMore>
++        <zeroOrMore>
++          <element name="bandwidth">
++            <attribute name="initiator">
++              <ref name="unsignedInt"/>
++            </attribute>
++            <attribute name="target">
++              <ref name="unsignedInt"/>
++            </attribute>
++            <attribute name="type">
++              <choice>
++                <value>access</value>
++                <value>read</value>
++                <value>write</value>
++              </choice>
++            </attribute>
++            <attribute name="value">
++              <ref name="unsignedInt"/>
++            </attribute>
++            <attribute name="unit">
++              <ref name="unit"/>
++            </attribute>
++          </element>
++        </zeroOrMore>
++      </interleave>
++    </element>
++  </define>
++
+   <!-- Memory as an attribute is in KiB, no way to express a unit -->
+   <define name="memoryKB">
+     <data type="unsignedLong"/>
+diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c
+index a805336d16..5c764190c3 100644
+--- a/src/conf/numa_conf.c
++++ b/src/conf/numa_conf.c
+@@ -59,9 +59,37 @@ VIR_ENUM_IMPL(virDomainMemoryAccess,
+               "private",
+ );
+ 
++VIR_ENUM_IMPL(virDomainCacheAssociativity,
++              VIR_DOMAIN_CACHE_ASSOCIATIVITY_LAST,
++              "none",
++              "direct",
++              "full",
++);
++
++VIR_ENUM_IMPL(virDomainCachePolicy,
++              VIR_DOMAIN_CACHE_POLICY_LAST,
++              "none",
++              "writeback",
++              "writethrough",
++);
++
++VIR_ENUM_IMPL(virDomainMemoryLatency,
++              VIR_DOMAIN_MEMORY_LATENCY_LAST,
++              "none",
++              "access",
++              "read",
++              "write"
++);
++
+ typedef struct _virDomainNumaDistance virDomainNumaDistance;
+ typedef virDomainNumaDistance *virDomainNumaDistancePtr;
+ 
++typedef struct _virDomainNumaCache virDomainNumaCache;
++typedef virDomainNumaCache *virDomainNumaCachePtr;
++
++typedef struct _virDomainNumaInterconnect virDomainNumaInterconnect;
++typedef virDomainNumaInterconnect *virDomainNumaInterconnectPtr;
++
+ typedef struct _virDomainNumaNode virDomainNumaNode;
+ typedef virDomainNumaNode *virDomainNumaNodePtr;
+ 
+@@ -86,9 +114,30 @@ struct _virDomainNuma {
+             unsigned int cellid;
+         } *distances;           /* remote node distances */
+         size_t ndistances;
++
++        struct _virDomainNumaCache {
++            unsigned int level; /* cache level */
++            unsigned int size;  /* cache size */
++            unsigned int line;  /* line size, !!! in bytes !!! */
++            virDomainCacheAssociativity associativity; /* cache associativity */
++            virDomainCachePolicy policy; /* cache policy */
++        } *caches;
++        size_t ncaches;
+     } *mem_nodes;           /* guest node configuration */
+     size_t nmem_nodes;
+ 
++    struct _virDomainNumaInterconnect {
++        virDomainNumaInterconnectType type;  /* whether structure describes latency
++                                                or bandwidth */
++        unsigned int initiator; /* the initiator NUMA node */
++        unsigned int target;    /* the target NUMA node */
++        unsigned int cache;     /* the target cache on @target; if 0 then the
++                                   memory on @target */
++        virDomainMemoryLatency accessType;  /* what type of access is defined */
++        unsigned long value;    /* value itself */
++    } *interconnects;
++    size_t ninterconnects;
++
+     /* Future NUMA tuning related stuff should go here. */
+ };
+ 
+@@ -368,9 +417,13 @@ virDomainNumaFree(virDomainNumaPtr numa)
+ 
+         if (numa->mem_nodes[i].ndistances > 0)
+             VIR_FREE(numa->mem_nodes[i].distances);
++
++        VIR_FREE(numa->mem_nodes[i].caches);
+     }
+     VIR_FREE(numa->mem_nodes);
+ 
++    VIR_FREE(numa->interconnects);
++
+     VIR_FREE(numa);
+ }
+ 
+@@ -841,6 +894,97 @@ virDomainNumaDefNodeDistanceParseXML(virDomainNumaPtr def,
+     return ret;
+ }
+ 
++
++static int
++virDomainNumaDefNodeCacheParseXML(virDomainNumaPtr def,
++                                  xmlXPathContextPtr ctxt,
++                                  unsigned int cur_cell)
++{
++    g_autofree xmlNodePtr *nodes = NULL;
++    int n;
++    size_t i;
++
++    if ((n = virXPathNodeSet("./cache", ctxt, &nodes)) < 0)
++        return -1;
++
++    def->mem_nodes[cur_cell].caches = g_new0(virDomainNumaCache, n);
++
++    for (i = 0; i < n; i++) {
++        VIR_XPATH_NODE_AUTORESTORE(ctxt);
++        virDomainNumaCachePtr cache = &def->mem_nodes[cur_cell].caches[i];
++        g_autofree char *tmp = NULL;
++        unsigned int level;
++        int associativity;
++        int policy;
++        unsigned long long size;
++        unsigned long long line;
++
++        if (!(tmp = virXMLPropString(nodes[i], "level"))) {
++            virReportError(VIR_ERR_XML_ERROR,
++                           _("Missing 'level' attribute in cache "
++                             "element for NUMA node %d"),
++                           cur_cell);
++            return -1;
++        }
++
++        if (virStrToLong_uip(tmp, NULL, 10, &level) < 0 ||
++            level == 0) {
++            virReportError(VIR_ERR_XML_ERROR,
++                           _("Invalid 'level' attribute in cache "
++                             "element for NUMA node %d"),
++                           cur_cell);
++            return -1;
++        }
++        VIR_FREE(tmp);
++
++        if (!(tmp = virXMLPropString(nodes[i], "associativity"))) {
++            virReportError(VIR_ERR_XML_ERROR,
++                           _("Missing 'associativity' attribute in cache "
++                             "element for NUMA node %d"),
++                           cur_cell);
++            return -1;
++        }
++
++        if ((associativity = virDomainCacheAssociativityTypeFromString(tmp)) < 0) {
++            virReportError(VIR_ERR_XML_ERROR,
++                           _("Invalid cache associativity '%s'"),
++                           tmp);
++            return -1;
++        }
++        VIR_FREE(tmp);
++
++        if (!(tmp = virXMLPropString(nodes[i], "policy"))) {
++            virReportError(VIR_ERR_XML_ERROR,
++                           _("Missing 'policy' attribute in cache "
++                             "element for NUMA node %d"),
++                           cur_cell);
++        }
++
++        if ((policy = virDomainCachePolicyTypeFromString(tmp)) < 0) {
++            virReportError(VIR_ERR_XML_ERROR,
++                           _("Invalid cache policy '%s'"),
++                           tmp);
++            return -1;
++        }
++        VIR_FREE(tmp);
++
++        ctxt->node = nodes[i];
++        if (virDomainParseMemory("./size/@value", "./size/unit",
++                                 ctxt, &size, true, false) < 0)
++            return -1;
++
++        if (virParseScaledValue("./line/@value", "./line/unit",
++                                ctxt, &line, 1, ULLONG_MAX, true) < 0)
++            return -1;
++
++        *cache = (virDomainNumaCache){level, size, line, associativity, policy};
++        def->mem_nodes[cur_cell].ncaches++;
++    }
++
++    return 0;
++}
++
++
+ int
+ virDomainNumaDefParseXML(virDomainNumaPtr def,
+                          xmlXPathContextPtr ctxt)
+@@ -867,6 +1011,7 @@ virDomainNumaDefParseXML(virDomainNumaPtr def,
+     def->nmem_nodes = n;
+ 
+     for (i = 0; i < n; i++) {
++        VIR_XPATH_NODE_AUTORESTORE(ctxt);
+         int rc;
+         unsigned int cur_cell = i;
+ 
+@@ -953,7 +1098,109 @@ virDomainNumaDefParseXML(virDomainNumaPtr def,
+ 
+         /* Parse NUMA distances info */
+         if (virDomainNumaDefNodeDistanceParseXML(def, ctxt, cur_cell) < 0)
++            goto cleanup;
++
++        /* Parse cache info */
++        if (virDomainNumaDefNodeCacheParseXML(def, ctxt, cur_cell) < 0)
++            goto cleanup;
++    }
++
++    VIR_FREE(nodes);
++    if ((n = virXPathNodeSet("./cpu/numa[1]/interconnects[1]/latency|"
++                             "./cpu/numa[1]/interconnects[1]/bandwidth", ctxt, &nodes)) < 0)
++        goto cleanup;
++
++    def->interconnects = g_new0(virDomainNumaInterconnect, n);
++    for (i = 0; i < n; i++) {
++        virDomainNumaInterconnectType type;
++        unsigned int initiator;
++        unsigned int target;
++        unsigned int cache = 0;
++        int accessType;
++        unsigned long long value;
++
++        if (virXMLNodeNameEqual(nodes[i], "latency")) {
++            type = VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_LATENCY;
++
++            if (!(tmp = virXMLPropString(nodes[i], "value"))) {
++                virReportError(VIR_ERR_XML_ERROR, "%s",
++                               _("Missing 'value' attribute in NUMA interconnects"));
+                 goto cleanup;
++            }
++
++            if (virStrToLong_ullp(tmp, NULL, 10, &value) < 0) {
++                virReportError(VIR_ERR_XML_ERROR, "%s",
++                               _("Invalid 'value' attribute in NUMA interconnects"));
++                goto cleanup;
++            }
++            VIR_FREE(tmp);
++        } else if (virXMLNodeNameEqual(nodes[i], "bandwidth")) {
++            VIR_XPATH_NODE_AUTORESTORE(ctxt);
++            type = VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_BANDWIDTH;
++
++            ctxt->node = nodes[i];
++
++            if (virDomainParseMemory("./@value", "./@unit", ctxt, &value, true, false) < 0)
++                goto cleanup;
++        } else {
++            /* Ignore yet unknown child elements. */
++            continue;
++        }
++
++        if (!(tmp = virXMLPropString(nodes[i], "initiator"))) {
++            virReportError(VIR_ERR_XML_ERROR, "%s",
++                           _("Missing 'initiator' attribute in NUMA interconnects"));
++            goto cleanup;
++        }
++
++        if (virStrToLong_uip(tmp, NULL, 10, &initiator) < 0) {
++            virReportError(VIR_ERR_XML_ERROR, "%s",
++                           _("Invalid 'initiator' attribute in NUMA interconnects"));
++            goto cleanup;
++        }
++        VIR_FREE(tmp);
++
++        if (!(tmp = virXMLPropString(nodes[i], "target"))) {
++            virReportError(VIR_ERR_XML_ERROR, "%s",
++                           _("Missing 'target' attribute in NUMA interconnects"));
++            goto cleanup;
++        }
++
++        if (virStrToLong_uip(tmp, NULL, 10, &target) < 0) {
++            virReportError(VIR_ERR_XML_ERROR, "%s",
++                           _("Invalid 'target' attribute in NUMA interconnects"));
++            goto cleanup;
++        }
++        VIR_FREE(tmp);
++
++
++        /* cache attribute is optional */
++        if ((tmp = virXMLPropString(nodes[i], "cache"))) {
++            if (virStrToLong_uip(tmp, NULL, 10, &cache) < 0 ||
++                cache == 0) {
++                virReportError(VIR_ERR_XML_ERROR, "%s",
++                               _("Invalid 'cache' attribute in NUMA interconnects"));
++                goto cleanup;
++            }
++        }
++        VIR_FREE(tmp);
++
++        if (!(tmp = virXMLPropString(nodes[i], "type"))) {
++            virReportError(VIR_ERR_XML_ERROR, "%s",
++                           _("Missing 'type' attribute in NUMA interconnects"));
++            goto cleanup;
++        }
++
++        if ((accessType = virDomainMemoryLatencyTypeFromString(tmp)) <= 0) {
++            virReportError(VIR_ERR_XML_ERROR, "%s",
++                           _("Invalid 'type' attribute in NUMA interconnects"));
++            goto cleanup;
++        }
++        VIR_FREE(tmp);
++
++        def->interconnects[i] = (virDomainNumaInterconnect) {type, initiator, target,
++                                                             cache, accessType, value};
++        def->ninterconnects++;
+     }
+ 
+     ret = 0;
+@@ -983,6 +1230,7 @@ virDomainNumaDefFormatXML(virBufferPtr buf,
+     for (i = 0; i < ncells; i++) {
+         virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(def, i);
+         int ndistances;
++        size_t ncaches;
+ 
+         memAccess = virDomainNumaGetNodeMemoryAccessMode(def, i);
+         discard = virDomainNumaGetNodeDiscard(def, i);
+@@ -1009,30 +1257,107 @@ virDomainNumaDefFormatXML(virBufferPtr buf,
+                               virTristateBoolTypeToString(discard));
+ 
+         ndistances = def->mem_nodes[i].ndistances;
+-        if (ndistances == 0) {
++        ncaches = def->mem_nodes[i].ncaches;
++        if (ndistances == 0 && ncaches == 0) {
+             virBufferAddLit(buf, "/>\n");
+         } else {
+             size_t j;
+-            virDomainNumaDistancePtr distances = def->mem_nodes[i].distances;
+ 
+             virBufferAddLit(buf, ">\n");
+             virBufferAdjustIndent(buf, 2);
+-            virBufferAddLit(buf, "<distances>\n");
+-            virBufferAdjustIndent(buf, 2);
+-            for (j = 0; j < ndistances; j++) {
+-                if (distances[j].value) {
+-                    virBufferAddLit(buf, "<sibling");
+-                    virBufferAsprintf(buf, " id='%d'", distances[j].cellid);
+-                    virBufferAsprintf(buf, " value='%d'", distances[j].value);
+-                    virBufferAddLit(buf, "/>\n");
++
++            if (ndistances) {
++                virDomainNumaDistancePtr distances = def->mem_nodes[i].distances;
++
++                virBufferAddLit(buf, "<distances>\n");
++                virBufferAdjustIndent(buf, 2);
++                for (j = 0; j < ndistances; j++) {
++                    if (distances[j].value) {
++                        virBufferAddLit(buf, "<sibling");
++                        virBufferAsprintf(buf, " id='%d'", distances[j].cellid);
++                        virBufferAsprintf(buf, " value='%d'", distances[j].value);
++                        virBufferAddLit(buf, "/>\n");
++                    }
+                 }
++                virBufferAdjustIndent(buf, -2);
++                virBufferAddLit(buf, "</distances>\n");
++            }
++
++            for (j = 0; j < ncaches; j++) {
++                virDomainNumaCachePtr cache = &def->mem_nodes[i].caches[j];
++
++                virBufferAsprintf(buf, "<cache level='%u'", cache->level);
++                if (cache->associativity) {
++                    virBufferAsprintf(buf, " associativity='%s'",
++                                      virDomainCacheAssociativityTypeToString(cache->associativity));
++                }
++
++                if (cache->policy) {
++                    virBufferAsprintf(buf, " policy='%s'",
++                                      virDomainCachePolicyTypeToString(cache->policy));
++                }
++                virBufferAddLit(buf, ">\n");
++
++                virBufferAdjustIndent(buf, 2);
++                virBufferAsprintf(buf,
++                                  "<size value='%u' unit='KiB'/>\n",
++                                  cache->size);
++
++                if (cache->line) {
++                    virBufferAsprintf(buf,
++                                      "<line value='%u' unit='B'/>\n",
++                                      cache->line);
++                }
++
++                virBufferAdjustIndent(buf, -2);
++                virBufferAddLit(buf, "</cache>\n");
+             }
+-            virBufferAdjustIndent(buf, -2);
+-            virBufferAddLit(buf, "</distances>\n");
+             virBufferAdjustIndent(buf, -2);
+             virBufferAddLit(buf, "</cell>\n");
+         }
+     }
++
++    if (def->ninterconnects) {
++        virBufferAddLit(buf, "<interconnects>\n");
++        virBufferAdjustIndent(buf, 2);
++    }
++
++    for (i = 0; i < def->ninterconnects; i++) {
++        virDomainNumaInterconnectPtr l = &def->interconnects[i];
++
++        switch (l->type) {
++        case VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_LATENCY:
++            virBufferAddLit(buf, "<latency");
++            break;
++        case VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_BANDWIDTH:
++            virBufferAddLit(buf, "<bandwidth");
++        }
++
++        virBufferAsprintf(buf,
++                          " initiator='%u' target='%u'",
++                          l->initiator, l->target);
++
++        if (l->cache > 0) {
++            virBufferAsprintf(buf,
++                              " cache='%u'",
++                              l->cache);
++        }
++
++        virBufferAsprintf(buf,
++                          " type='%s' value='%lu'",
++                          virDomainMemoryLatencyTypeToString(l->accessType),
++                          l->value);
++
++        if (l->type == VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_BANDWIDTH)
++            virBufferAddLit(buf, " unit='KiB'");
++        virBufferAddLit(buf, "/>\n");
++    }
++
++    if (def->ninterconnects) {
++        virBufferAdjustIndent(buf, -2);
++        virBufferAddLit(buf, "</interconnects>\n");
++    }
++
+     virBufferAdjustIndent(buf, -2);
+     virBufferAddLit(buf, "</numa>\n");
+ 
+diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h
+index 6808439a7c..5043c5a6d4 100644
+--- a/src/conf/numa_conf.h
++++ b/src/conf/numa_conf.h
+@@ -52,6 +52,39 @@ typedef enum {
+ } virDomainMemoryAccess;
+ VIR_ENUM_DECL(virDomainMemoryAccess);
+ 
++typedef enum {
++    VIR_DOMAIN_CACHE_ASSOCIATIVITY_NONE,    /* No associativity */
++    VIR_DOMAIN_CACHE_ASSOCIATIVITY_DIRECT,  /* Direct mapped cache */
++    VIR_DOMAIN_CACHE_ASSOCIATIVITY_FULL,    /* Fully associative cache */
++
++    VIR_DOMAIN_CACHE_ASSOCIATIVITY_LAST
++} virDomainCacheAssociativity;
++VIR_ENUM_DECL(virDomainCacheAssociativity);
++
++typedef enum {
++    VIR_DOMAIN_CACHE_POLICY_NONE,           /* No policy */
++    VIR_DOMAIN_CACHE_POLICY_WRITEBACK,      /* Write-back policy */
++    VIR_DOMAIN_CACHE_POLICY_WRITETHROUGH,   /* Write-through policy */
++
++    VIR_DOMAIN_CACHE_POLICY_LAST
++} virDomainCachePolicy;
++VIR_ENUM_DECL(virDomainCachePolicy);
++
++typedef enum {
++    VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_LATENCY,
++    VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_BANDWIDTH,
++} virDomainNumaInterconnectType;
++
++typedef enum {
++    VIR_DOMAIN_MEMORY_LATENCY_NONE = 0, /* No memory latency defined */
++    VIR_DOMAIN_MEMORY_LATENCY_ACCESS,   /* Access latency */
++    VIR_DOMAIN_MEMORY_LATENCY_READ,     /* Read latency */
++    VIR_DOMAIN_MEMORY_LATENCY_WRITE,    /* Write latency */
++
++    VIR_DOMAIN_MEMORY_LATENCY_LAST
++} virDomainMemoryLatency;
++VIR_ENUM_DECL(virDomainMemoryLatency);
++
+ 
+ virDomainNumaPtr virDomainNumaNew(void);
+ void virDomainNumaFree(virDomainNumaPtr numa);
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index acb25eb8c8..de95e3b116 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -808,8 +808,14 @@ virNodeDeviceDeleteVport;
+ virNodeDeviceGetParentName;
+ 
+ # conf/numa_conf.h
++virDomainCacheAssociativityTypeFromString;
++virDomainCacheAssociativityTypeToString;
++virDomainCachePolicyTypeFromString;
++virDomainCachePolicyTypeToString;
+ virDomainMemoryAccessTypeFromString;
+ virDomainMemoryAccessTypeToString;
++virDomainMemoryLatencyTypeFromString;
++virDomainMemoryLatencyTypeToString;
+ virDomainNumaCheckABIStability;
+ virDomainNumaEquals;
+ virDomainNumaFree;
+diff --git a/tests/qemuxml2argvdata/numatune-hmat.xml b/tests/qemuxml2argvdata/numatune-hmat.xml
+new file mode 100644
+index 0000000000..83f0b56c9b
+--- /dev/null
++++ b/tests/qemuxml2argvdata/numatune-hmat.xml
+@@ -0,0 +1,52 @@
++<domain type='qemu'>
++  <name>QEMUGuest</name>
++  <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>8388608</memory>
++  <currentMemory unit='KiB'>8388608</currentMemory>
++  <vcpu placement='static'>12</vcpu>
++  <os>
++    <type arch='x86_64' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <features>
++    <acpi/>
++    <apic/>
++    <pae/>
++  </features>
++  <cpu>
++    <numa>
++      <cell id='0' cpus='0-3' memory='2097152' unit='KiB'>
++        <cache level='1' associativity='direct' policy='writeback'>
++          <size value='10' unit='KiB'/>
++          <line value='8' unit='B'/>
++        </cache>
++      </cell>
++      <cell id='1' cpus='4-7' memory='2097152' unit='KiB'/>
++      <cell id='2' cpus='8-11' memory='2097152' unit='KiB'/>
++      <cell id='3' memory='2097152' unit='KiB'/>
++      <cell id='4' memory='2097152' unit='KiB'/>
++      <cell id='5' memory='2097152' unit='KiB'/>
++      <interconnects>
++        <latency initiator='0' target='0' type='access' value='5'/>
++        <latency initiator='0' target='0' cache='1' type='access' value='10'/>
++        <bandwidth initiator='0' target='0' type='access' value='204800' unit='KiB'/>
++      </interconnects>
++    </numa>
++  </cpu>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>restart</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-x86_64</emulator>
++    <controller type='usb' index='0'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
++    </controller>
++    <controller type='pci' index='0' model='pci-root'/>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <memballoon model='virtio'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
++    </memballoon>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2xmloutdata/numatune-hmat.xml b/tests/qemuxml2xmloutdata/numatune-hmat.xml
+new file mode 120000
+index 0000000000..6903a80ab1
+--- /dev/null
++++ b/tests/qemuxml2xmloutdata/numatune-hmat.xml
+@@ -0,0 +1 @@
++../qemuxml2argvdata/numatune-hmat.xml
+\ No newline at end of file
+diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
+index 1ddeba30f0..de1d720e1d 100644
+--- a/tests/qemuxml2xmltest.c
++++ b/tests/qemuxml2xmltest.c
+@@ -1106,6 +1106,7 @@ mymain(void)
+     DO_TEST("numatune-memnode-no-memory", QEMU_CAPS_OBJECT_MEMORY_FILE);
+     DO_TEST("numatune-distances", QEMU_CAPS_NUMA, QEMU_CAPS_NUMA_DIST);
+     DO_TEST("numatune-no-vcpu", QEMU_CAPS_NUMA);
++    DO_TEST("numatune-hmat", NONE);
+ 
+     DO_TEST("bios-nvram", NONE);
+     DO_TEST("bios-nvram-os-interleave", NONE);
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-conf-Validate-NUMA-HMAT-configuration.patch b/SOURCES/libvirt-conf-Validate-NUMA-HMAT-configuration.patch
new file mode 100644
index 0000000..1ca6905
--- /dev/null
+++ b/SOURCES/libvirt-conf-Validate-NUMA-HMAT-configuration.patch
@@ -0,0 +1,166 @@
+From 0ae283a1cb5224f3eb4fa32706e9b9c212577e51 Mon Sep 17 00:00:00 2001
+Message-Id: <0ae283a1cb5224f3eb4fa32706e9b9c212577e51@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 7 Oct 2020 18:45:40 +0200
+Subject: [PATCH] conf: Validate NUMA HMAT configuration
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There are several restrictions, for instance @initiator and
+@target have to refer to existing NUMA nodes (daa), @cache has to
+refer to a defined cache level and so on.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit f0611fe8830543d03d1871422f8c542453f0c8db)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <e8488a2e49fa251dd0e2ab51f5ab627e3b265440.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c |  3 ++
+ src/conf/numa_conf.c   | 99 ++++++++++++++++++++++++++++++++++++++++++
+ src/conf/numa_conf.h   |  1 +
+ 3 files changed, 103 insertions(+)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 3229d5ec95..f41559f33e 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -7144,6 +7144,9 @@ virDomainDefValidateInternal(const virDomainDef *def,
+     if (virDomainDefCputuneValidate(def) < 0)
+         return -1;
+ 
++    if (virDomainNumaDefValidate(def->numa) < 0)
++        return -1;
++
+     return 0;
+ }
+ 
+diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c
+index 5c764190c3..c90fb01bb6 100644
+--- a/src/conf/numa_conf.c
++++ b/src/conf/numa_conf.c
+@@ -1365,6 +1365,105 @@ virDomainNumaDefFormatXML(virBufferPtr buf,
+ }
+ 
+ 
++int
++virDomainNumaDefValidate(const virDomainNuma *def)
++{
++    size_t i;
++    size_t j;
++
++    if (!def)
++        return 0;
++
++    for (i = 0; i < def->nmem_nodes; i++) {
++        const virDomainNumaNode *node = &def->mem_nodes[i];
++        g_autoptr(virBitmap) levelsSeen = virBitmapNewEmpty();
++
++        for (j = 0; j < node->ncaches; j++) {
++            const virDomainNumaCache *cache = &node->caches[j];
++
++            /* Relax this if there's ever fourth layer of cache */
++            if (cache->level > 3) {
++                virReportError(VIR_ERR_XML_ERROR, "%s",
++                               _("Ain't nobody heard of that much cache level"));
++                return -1;
++            }
++
++            if (virBitmapIsBitSet(levelsSeen, cache->level)) {
++                virReportError(VIR_ERR_XML_ERROR,
++                               _("Cache level '%u' already defined"),
++                               cache->level);
++                return -1;
++            }
++
++            if (virBitmapSetBitExpand(levelsSeen, cache->level))
++                return -1;
++        }
++    }
++
++    for (i = 0; i < def->ninterconnects; i++) {
++        const virDomainNumaInterconnect *l = &def->interconnects[i];
++
++        if (l->initiator >= def->nmem_nodes) {
++            virReportError(VIR_ERR_XML_ERROR, "%s",
++                           _("'initiator' refers to a non-existent NUMA node"));
++            return -1;
++        }
++
++        if (l->target >= def->nmem_nodes) {
++            virReportError(VIR_ERR_XML_ERROR, "%s",
++                           _("'target' refers to a non-existent NUMA node"));
++            return -1;
++        }
++
++        if (!def->mem_nodes[l->initiator].cpumask) {
++            virReportError(VIR_ERR_XML_ERROR, "%s",
++                           _("NUMA nodes without CPUs can't be initiator"));
++            return -1;
++        }
++
++        if (l->cache > 0) {
++            for (j = 0; j < def->mem_nodes[l->target].ncaches; j++) {
++                const virDomainNumaCache *cache = def->mem_nodes[l->target].caches;
++
++                if (l->cache == cache->level)
++                    break;
++            }
++
++            if (j == def->mem_nodes[l->target].ncaches) {
++                virReportError(VIR_ERR_XML_ERROR, "%s",
++                               _("'cache' refers to a non-existent NUMA node cache"));
++                return -1;
++            }
++        }
++
++        for (j = 0; j < i; j++) {
++            const virDomainNumaInterconnect *ll = &def->interconnects[j];
++
++            if (l->type == ll->type &&
++                l->initiator == ll->initiator &&
++                l->target == ll->target &&
++                l->cache == ll->cache &&
++                l->accessType == ll->accessType) {
++                virReportError(VIR_ERR_XML_ERROR, "%s",
++                               _("Duplicate info for NUMA latencies"));
++                return -1;
++            }
++
++
++            if (l->initiator != l->target &&
++                l->initiator == ll->target &&
++                l->target == ll->initiator) {
++                virReportError(VIR_ERR_XML_ERROR, "%s",
++                               _("Link already defined"));
++                return -1;
++            }
++        }
++    }
++
++    return 0;
++}
++
++
+ unsigned int
+ virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa)
+ {
+diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h
+index 5043c5a6d4..2963004c94 100644
+--- a/src/conf/numa_conf.h
++++ b/src/conf/numa_conf.h
+@@ -217,5 +217,6 @@ bool virDomainNumatuneNodeSpecified(virDomainNumaPtr numatune,
+ 
+ int virDomainNumaDefParseXML(virDomainNumaPtr def, xmlXPathContextPtr ctxt);
+ int virDomainNumaDefFormatXML(virBufferPtr buf, virDomainNumaPtr def);
++int virDomainNumaDefValidate(const virDomainNuma *def);
+ 
+ unsigned int virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa);
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-conf-properly-clear-out-autogenerated-macvtap-names-when-formatting-parsing.patch b/SOURCES/libvirt-conf-properly-clear-out-autogenerated-macvtap-names-when-formatting-parsing.patch
new file mode 100644
index 0000000..0133af5
--- /dev/null
+++ b/SOURCES/libvirt-conf-properly-clear-out-autogenerated-macvtap-names-when-formatting-parsing.patch
@@ -0,0 +1,117 @@
+From b2e0155b59ae9f038bcf21da7c6b7fb0a99a7b67 Mon Sep 17 00:00:00 2001
+Message-Id: <b2e0155b59ae9f038bcf21da7c6b7fb0a99a7b67@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Tue, 1 Dec 2020 22:01:00 -0500
+Subject: [PATCH] conf: properly clear out autogenerated macvtap names when
+ formatting/parsing
+
+Back when macvtap support was added in commit 315baab9443 in Feb. 2010
+(libvirt-0.7.7), it was setup to autogenerate a name for the device if
+one wasn't supplied, in the pattern "macvtap%d" (or "macvlan%d"),
+similar to the way an unspecified standard tap device name will lead
+to an autogenerated "vnet%d".
+
+As a matter of fact, in commit ca1b7cc8e45 added in May 2010, the code
+was changed to *always* ignore a supplied device name for macvtap
+interfaces by deleting *any* name immediately during the <interface>
+parsing (this was intended to prevent one domain which had failed to
+completely start from deleting the macvtap device of another domain
+which had subsequently been provided the same device name (this will
+seem mildly ironic later). This was later fixed to only clear the
+device name when inactive XML was being parsed. HOWEVER - this was
+only done if the xml was <interface type='direct'> - autogenerated
+names were not cleared for <interface type='network'> (which could
+also result in a macvtap device).
+
+Although the names of "vnetX" tap devices had always been
+automatically cleared when parsing <interface> (see commit d1304583d
+from July 2008 (!)), at the time macvtap support was added, both vnetX
+and macvtapX device names were always included when formatting the
+XML.
+
+Then in commit a8be259d0cc (July 2011, libvirt-0.9.4), <interface>
+formatting was changed to also clear out "vnetX" device names during
+XML formatting as well. However the same treatment wasn't given to
+"macvtapX".
+
+Now in 2020, there has been a report that a failed migration leads to
+the macvtap device of some other unrelated guest on the destination
+host losing its network connectivity. It was determined that this was
+due to the domain XML in the migration containing a macvtap device
+name, e.g. "macvtap0", that was already in use by the other guest on
+the destination. Normally this wouldn't be a problem, because libvirt
+would see that the device was already in use, and then find a
+different unused name. But in this case, other external problems were
+causing the migration to fail prior to selecting a macvtap device and
+successfully opening it, and during error recovery, qemuProcessStop()
+was called, which went through all def->nets objects and (if they were
+macvtap) deleted the device specified in net->ifname; since libvirt
+hadn't gotten to the point of replacing the incoming "macvtap0" with
+the name of a device it actually created for this guest, that meant
+that "macvtap0" was deleted, *even though it was currently in use by a
+different guest*!
+
+Whew!
+
+So, it turns out that when formatting "migratable" XML, "vnetX"
+devices are omitted, just as when formatting "inactive" XML. By making
+the code in both interface parsing and formatting consistent for
+"vnetX", "macvtapX", and "macvlanX", we can thus make sure that the
+autogenerated (and unneeded / completely *not* wanted) macvtap device
+name will not be sent with the migration XML. This way when a
+migration fails, net->ifname will be NULL, and libvirt won't have any
+device to try and (erroneously) delete.
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 282d135ddbb7203565cd5527b451469b14953994)
+
+https://bugzilla.redhat.com/1872610
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20201202030100.458879-1-laine@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/conf/domain_conf.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index f41559f33e..cd5c15f297 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -12183,14 +12183,6 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
+         }
+ 
+         def->data.direct.linkdev = g_steal_pointer(&dev);
+-
+-        if (ifname &&
+-            flags & VIR_DOMAIN_DEF_PARSE_INACTIVE &&
+-            (STRPREFIX(ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) ||
+-             STRPREFIX(ifname, VIR_NET_GENERATED_MACVLAN_PREFIX))) {
+-            VIR_FREE(ifname);
+-        }
+-
+         break;
+ 
+     case VIR_DOMAIN_NET_TYPE_HOSTDEV:
+@@ -12238,6 +12230,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
+     if (def->managed_tap != VIR_TRISTATE_BOOL_NO && ifname &&
+         (flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) &&
+         (STRPREFIX(ifname, VIR_NET_GENERATED_TAP_PREFIX) ||
++         STRPREFIX(ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) ||
++         STRPREFIX(ifname, VIR_NET_GENERATED_MACVLAN_PREFIX) ||
+          (prefix && STRPREFIX(ifname, prefix)))) {
+         /* An auto-generated target name, blank it out */
+         VIR_FREE(ifname);
+@@ -25996,6 +25990,8 @@ virDomainNetDefFormat(virBufferPtr buf,
+         (def->managed_tap == VIR_TRISTATE_BOOL_NO ||
+          !((flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE) &&
+            (STRPREFIX(def->ifname, VIR_NET_GENERATED_TAP_PREFIX) ||
++            STRPREFIX(def->ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) ||
++            STRPREFIX(def->ifname, VIR_NET_GENERATED_MACVLAN_PREFIX) ||
+             (prefix && STRPREFIX(def->ifname, prefix)))))) {
+         /* Skip auto-generated target names for inactive config. */
+         virBufferEscapeString(&attrBuf, " dev='%s'", def->ifname);
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-cpu_map-Add-EPYC-Milan-x86-CPU-model.patch b/SOURCES/libvirt-cpu_map-Add-EPYC-Milan-x86-CPU-model.patch
new file mode 100644
index 0000000..3257983
--- /dev/null
+++ b/SOURCES/libvirt-cpu_map-Add-EPYC-Milan-x86-CPU-model.patch
@@ -0,0 +1,145 @@
+From b5716d1b191eb52cd88d7b94cb9bf0186f3e427b Mon Sep 17 00:00:00 2001
+Message-Id: <b5716d1b191eb52cd88d7b94cb9bf0186f3e427b@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Wed, 3 Mar 2021 11:11:54 +0100
+Subject: [PATCH] cpu_map: Add EPYC-Milan x86 CPU model
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Introduced in QEMU 6.0.0 by 623972ceae091b31331ae4a1dc94fe5cbb891937
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit f321a4822e9fa6542e48a78611989ecd9acaa83a)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1926864
+
+Conflicts:
+	src/cpu_map/index.xml
+            - context: commit 82bebba1803c63a733e17f5ab2618e020e4abd8d
+              "cpu_map: Unify apostrophe and quotation mark usage" was
+              not backported
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Message-Id: <715abc0f90faafb7daa193dd24bad65046c36de0.1614766279.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/cpu_map/index.xml          |  1 +
+ src/cpu_map/x86_EPYC-Milan.xml | 92 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 93 insertions(+)
+ create mode 100644 src/cpu_map/x86_EPYC-Milan.xml
+
+diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
+index 2f58261e6d..c3dda794b1 100644
+--- a/src/cpu_map/index.xml
++++ b/src/cpu_map/index.xml
+@@ -68,6 +68,7 @@
+     <include filename="x86_EPYC.xml"/>
+     <include filename="x86_EPYC-IBPB.xml"/>
+     <include filename="x86_EPYC-Rome.xml"/>
++    <include filename='x86_EPYC-Milan.xml'/>
+ 
+     <!-- Hygon CPU models -->
+     <include filename="x86_Dhyana.xml"/>
+diff --git a/src/cpu_map/x86_EPYC-Milan.xml b/src/cpu_map/x86_EPYC-Milan.xml
+new file mode 100644
+index 0000000000..53f0cd6aac
+--- /dev/null
++++ b/src/cpu_map/x86_EPYC-Milan.xml
+@@ -0,0 +1,92 @@
++<cpus>
++  <model name='EPYC-Milan'>
++    <decode host='on' guest='on'/>
++    <signature family='25' model='1'/>
++    <vendor name='AMD'/>
++    <feature name='3dnowprefetch'/>
++    <feature name='abm'/>
++    <feature name='adx'/>
++    <feature name='aes'/>
++    <feature name='amd-ssbd'/>
++    <feature name='amd-stibp'/>
++    <feature name='apic'/>
++    <feature name='arat'/>
++    <feature name='avx'/>
++    <feature name='avx2'/>
++    <feature name='bmi1'/>
++    <feature name='bmi2'/>
++    <feature name='clflush'/>
++    <feature name='clflushopt'/>
++    <feature name='clwb'/>
++    <feature name='clzero'/>
++    <feature name='cmov'/>
++    <feature name='cr8legacy'/>
++    <feature name='cx16'/>
++    <feature name='cx8'/>
++    <feature name='de'/>
++    <feature name='erms'/>
++    <feature name='f16c'/>
++    <feature name='fma'/>
++    <feature name='fpu'/>
++    <feature name='fsgsbase'/>
++    <feature name='fsrm'/>
++    <feature name='fxsr'/>
++    <feature name='fxsr_opt'/>
++    <feature name='ibpb'/>
++    <feature name='ibrs'/>
++    <feature name='invpcid'/>
++    <feature name='lahf_lm'/>
++    <feature name='lm'/>
++    <feature name='mca'/>
++    <feature name='mce'/>
++    <feature name='misalignsse'/>
++    <feature name='mmx'/>
++    <feature name='mmxext'/>
++    <feature name='movbe'/>
++    <feature name='msr'/>
++    <feature name='mtrr'/>
++    <feature name='npt'/>
++    <feature name='nrip-save'/>
++    <feature name='nx'/>
++    <feature name='osvw'/>
++    <feature name='pae'/>
++    <feature name='pat'/>
++    <feature name='pcid'/>
++    <feature name='pclmuldq'/>
++    <feature name='pdpe1gb'/>
++    <feature name='perfctr_core'/>
++    <feature name='pge'/>
++    <feature name='pku'/>
++    <feature name='pni'/>
++    <feature name='popcnt'/>
++    <feature name='pse'/>
++    <feature name='pse36'/>
++    <feature name='rdpid'/>
++    <feature name='rdrand'/>
++    <feature name='rdseed'/>
++    <feature name='rdtscp'/>
++    <feature name='sep'/>
++    <feature name='sha-ni'/>
++    <feature name='smap'/>
++    <feature name='smep'/>
++    <feature name='sse'/>
++    <feature name='sse2'/>
++    <feature name='sse4.1'/>
++    <feature name='sse4.2'/>
++    <feature name='sse4a'/>
++    <feature name='ssse3'/>
++    <feature name='svm'/>
++    <feature name='svme-addr-check'/>
++    <feature name='syscall'/>
++    <feature name='tsc'/>
++    <feature name='umip'/>
++    <feature name='vme'/>
++    <feature name='wbnoinvd'/>
++    <feature name='xgetbv1'/>
++    <feature name='xsave'/>
++    <feature name='xsavec'/>
++    <feature name='xsaveerptr'/>
++    <feature name='xsaveopt'/>
++    <feature name='xsaves'/>
++  </model>
++</cpus>
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-cpu_map-Add-missing-AMD-SVM-features.patch b/SOURCES/libvirt-cpu_map-Add-missing-AMD-SVM-features.patch
new file mode 100644
index 0000000..b907c79
--- /dev/null
+++ b/SOURCES/libvirt-cpu_map-Add-missing-AMD-SVM-features.patch
@@ -0,0 +1,896 @@
+From 5936216b6e32392d785979bfd6ccafc5174ec519 Mon Sep 17 00:00:00 2001
+Message-Id: <5936216b6e32392d785979bfd6ccafc5174ec519@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Thu, 8 Oct 2020 18:01:23 +0200
+Subject: [PATCH] cpu_map: Add missing AMD SVM features
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 96a39aad705f8e37950109d11636085b212af790)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1861506
+
+Conflicts:
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-disabled.xml
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-enabled.xml
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-guest.xml
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-host.xml
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-json.xml
+	tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml
+	tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml
+	tests/domaincapsdata/qemu_5.1.0.x86_64.xml
+            - not present downstream
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Message-Id: <d55a2ddfc9aefcc833d3a370c7d70dfb2c0b7554.1602172344.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/cpu_map/x86_features.xml                  | 32 +++++++++++++++++++
+ .../x86_64-cpuid-A10-5800K-disabled.xml       |  1 +
+ .../x86_64-cpuid-A10-5800K-enabled.xml        |  1 +
+ .../x86_64-cpuid-A10-5800K-guest.xml          | 10 ++++++
+ .../x86_64-cpuid-A10-5800K-host.xml           | 10 ++++++
+ .../x86_64-cpuid-A10-5800K-json.xml           |  2 ++
+ ...86_64-cpuid-EPYC-7601-32-Core-disabled.xml |  1 +
+ ...x86_64-cpuid-EPYC-7601-32-Core-enabled.xml |  1 +
+ .../x86_64-cpuid-EPYC-7601-32-Core-guest.xml  | 10 ++++++
+ .../x86_64-cpuid-EPYC-7601-32-Core-host.xml   | 10 ++++++
+ ...-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml |  1 +
+ ...4-cpuid-EPYC-7601-32-Core-ibpb-enabled.xml |  1 +
+ ..._64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml | 10 ++++++
+ ...6_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml | 10 ++++++
+ ...6_64-cpuid-EPYC-7601-32-Core-ibpb-json.xml |  2 ++
+ .../x86_64-cpuid-EPYC-7601-32-Core-json.xml   |  2 ++
+ .../x86_64-cpuid-FX-8150-guest.xml            | 10 ++++++
+ .../cputestdata/x86_64-cpuid-FX-8150-host.xml | 10 ++++++
+ ...-cpuid-Hygon-C86-7185-32-core-disabled.xml |  1 +
+ ...4-cpuid-Hygon-C86-7185-32-core-enabled.xml |  1 +
+ ..._64-cpuid-Hygon-C86-7185-32-core-guest.xml | 10 ++++++
+ ...6_64-cpuid-Hygon-C86-7185-32-core-host.xml | 10 ++++++
+ ...6_64-cpuid-Hygon-C86-7185-32-core-json.xml |  2 ++
+ .../x86_64-cpuid-Opteron-1352-guest.xml       |  3 ++
+ .../x86_64-cpuid-Opteron-1352-host.xml        |  3 ++
+ .../x86_64-cpuid-Opteron-2350-disabled.xml    |  1 +
+ .../x86_64-cpuid-Opteron-2350-enabled.xml     |  1 +
+ .../x86_64-cpuid-Opteron-2350-guest.xml       |  3 ++
+ .../x86_64-cpuid-Opteron-2350-host.xml        |  3 ++
+ .../x86_64-cpuid-Opteron-2350-json.xml        |  1 +
+ .../x86_64-cpuid-Opteron-6234-disabled.xml    |  1 +
+ .../x86_64-cpuid-Opteron-6234-enabled.xml     |  1 +
+ .../x86_64-cpuid-Opteron-6234-guest.xml       | 10 ++++++
+ .../x86_64-cpuid-Opteron-6234-host.xml        | 10 ++++++
+ .../x86_64-cpuid-Opteron-6234-json.xml        |  2 ++
+ .../x86_64-cpuid-Opteron-6282-guest.xml       | 10 ++++++
+ .../x86_64-cpuid-Opteron-6282-host.xml        | 10 ++++++
+ .../x86_64-cpuid-Phenom-B95-disabled.xml      |  1 +
+ .../x86_64-cpuid-Phenom-B95-enabled.xml       |  1 +
+ .../x86_64-cpuid-Phenom-B95-guest.xml         |  4 +++
+ .../x86_64-cpuid-Phenom-B95-host.xml          |  4 +++
+ .../x86_64-cpuid-Phenom-B95-json.xml          |  2 ++
+ ...puid-Ryzen-7-1800X-Eight-Core-disabled.xml |  1 +
+ ...cpuid-Ryzen-7-1800X-Eight-Core-enabled.xml |  1 +
+ ...4-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml | 10 ++++++
+ ...64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml | 10 ++++++
+ ...64-cpuid-Ryzen-7-1800X-Eight-Core-json.xml |  2 ++
+ .../domaincapsdata/qemu_3.0.0-tcg.x86_64.xml  |  1 +
+ .../domaincapsdata/qemu_3.1.0-tcg.x86_64.xml  |  1 +
+ .../domaincapsdata/qemu_4.0.0-tcg.x86_64.xml  |  2 ++
+ .../domaincapsdata/qemu_4.1.0-tcg.x86_64.xml  |  2 ++
+ .../domaincapsdata/qemu_4.2.0-tcg.x86_64.xml  |  2 ++
+ .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml  |  2 ++
+ .../cpu-host-model-cmt.x86_64-4.0.0.args      |  6 ++--
+ 54 files changed, 256 insertions(+), 3 deletions(-)
+
+diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml
+index 5265b2989b..30d1375437 100644
+--- a/src/cpu_map/x86_features.xml
++++ b/src/cpu_map/x86_features.xml
+@@ -508,6 +508,38 @@
+     <cpuid eax_in='0x80000008' ebx='0x04000000'/>
+   </feature>
+ 
++  <!-- SVM features -->
++  <feature name='npt'>
++    <cpuid eax_in='0x8000000a' edx='0x00000001'/>
++  </feature>
++  <feature name='lbrv'>
++    <cpuid eax_in='0x8000000a' edx='0x00000002'/>
++  </feature>
++  <feature name='svm-lock'>
++    <cpuid eax_in='0x8000000a' edx='0x00000004'/>
++  </feature>
++  <feature name='nrip-save'>
++    <cpuid eax_in='0x8000000a' edx='0x00000008'/>
++  </feature>
++  <feature name='tsc-scale'>
++    <cpuid eax_in='0x8000000a' edx='0x00000010'/>
++  </feature>
++  <feature name='vmcb-clean'>
++    <cpuid eax_in='0x8000000a' edx='0x00000020'/>
++  </feature>
++  <feature name='flushbyasid'>
++    <cpuid eax_in='0x8000000a' edx='0x00000040'/>
++  </feature>
++  <feature name='decodeassists'>
++    <cpuid eax_in='0x8000000a' edx='0x00000080'/>
++  </feature>
++  <feature name='pause-filter'>
++    <cpuid eax_in='0x8000000a' edx='0x00000400'/>
++  </feature>
++  <feature name='pfthreshold'>
++    <cpuid eax_in='0x8000000a' edx='0x00001000'/>
++  </feature>
++
+   <!-- IA32_ARCH_CAPABILITIES features -->
+   <feature name='rdctl-no'>
+     <msr index='0x10a' edx='0x00000000' eax='0x00000001'/>
+diff --git a/tests/cputestdata/x86_64-cpuid-A10-5800K-disabled.xml b/tests/cputestdata/x86_64-cpuid-A10-5800K-disabled.xml
+index 6ed5b3573b..3bacf2cf95 100644
+--- a/tests/cputestdata/x86_64-cpuid-A10-5800K-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-A10-5800K-disabled.xml
+@@ -3,4 +3,5 @@
+   <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x08000008' edx='0x10000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01cab40c' edx='0x08000000'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x000014f6'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-A10-5800K-enabled.xml b/tests/cputestdata/x86_64-cpuid-A10-5800K-enabled.xml
+index 5cae0b7130..f6afbe2cb3 100644
+--- a/tests/cputestdata/x86_64-cpuid-A10-5800K-enabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-A10-5800K-enabled.xml
+@@ -3,4 +3,5 @@
+   <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0xb6b83203' edx='0x078bfbff'/>
+   <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x0000000a' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00210bf3' edx='0x26500800'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-A10-5800K-guest.xml b/tests/cputestdata/x86_64-cpuid-A10-5800K-guest.xml
+index 98a95e1c41..8401e53d30 100644
+--- a/tests/cputestdata/x86_64-cpuid-A10-5800K-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-A10-5800K-guest.xml
+@@ -22,4 +22,14 @@
+   <feature policy='require' name='perfctr_core'/>
+   <feature policy='require' name='perfctr_nb'/>
+   <feature policy='require' name='invtsc'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='lbrv'/>
++  <feature policy='require' name='svm-lock'/>
++  <feature policy='require' name='nrip-save'/>
++  <feature policy='require' name='tsc-scale'/>
++  <feature policy='require' name='vmcb-clean'/>
++  <feature policy='require' name='flushbyasid'/>
++  <feature policy='require' name='decodeassists'/>
++  <feature policy='require' name='pause-filter'/>
++  <feature policy='require' name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-A10-5800K-host.xml b/tests/cputestdata/x86_64-cpuid-A10-5800K-host.xml
+index cb90c967a3..2430adbfbc 100644
+--- a/tests/cputestdata/x86_64-cpuid-A10-5800K-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-A10-5800K-host.xml
+@@ -23,4 +23,14 @@
+   <feature name='perfctr_core'/>
+   <feature name='perfctr_nb'/>
+   <feature name='invtsc'/>
++  <feature name='npt'/>
++  <feature name='lbrv'/>
++  <feature name='svm-lock'/>
++  <feature name='nrip-save'/>
++  <feature name='tsc-scale'/>
++  <feature name='vmcb-clean'/>
++  <feature name='flushbyasid'/>
++  <feature name='decodeassists'/>
++  <feature name='pause-filter'/>
++  <feature name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-A10-5800K-json.xml b/tests/cputestdata/x86_64-cpuid-A10-5800K-json.xml
+index fa61b7b60b..51e6d2b660 100644
+--- a/tests/cputestdata/x86_64-cpuid-A10-5800K-json.xml
++++ b/tests/cputestdata/x86_64-cpuid-A10-5800K-json.xml
+@@ -11,6 +11,8 @@
+   <feature policy='require' name='cmp_legacy'/>
+   <feature policy='require' name='cr8legacy'/>
+   <feature policy='require' name='osvw'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='nrip-save'/>
+   <feature policy='disable' name='rdtscp'/>
+   <feature policy='disable' name='svm'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml
+index c26c9c7be3..25ef2d3314 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml
+@@ -5,4 +5,5 @@
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c2300c' edx='0x00000000'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
+   <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x000014f6'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-enabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-enabled.xml
+index 70b75f7115..e46908e981 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-enabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-enabled.xml
+@@ -5,4 +5,5 @@
+   <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x209c01ab' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000007' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x000003f3' edx='0x2e500800'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml
+index 612e571609..0053913327 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml
+@@ -15,4 +15,14 @@
+   <feature policy='require' name='invtsc'/>
+   <feature policy='require' name='clzero'/>
+   <feature policy='require' name='xsaveerptr'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='lbrv'/>
++  <feature policy='require' name='svm-lock'/>
++  <feature policy='require' name='nrip-save'/>
++  <feature policy='require' name='tsc-scale'/>
++  <feature policy='require' name='vmcb-clean'/>
++  <feature policy='require' name='flushbyasid'/>
++  <feature policy='require' name='decodeassists'/>
++  <feature policy='require' name='pause-filter'/>
++  <feature policy='require' name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml
+index 7498d924e2..7acab0a999 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml
+@@ -16,4 +16,14 @@
+   <feature name='invtsc'/>
+   <feature name='clzero'/>
+   <feature name='xsaveerptr'/>
++  <feature name='npt'/>
++  <feature name='lbrv'/>
++  <feature name='svm-lock'/>
++  <feature name='nrip-save'/>
++  <feature name='tsc-scale'/>
++  <feature name='vmcb-clean'/>
++  <feature name='flushbyasid'/>
++  <feature name='decodeassists'/>
++  <feature name='pause-filter'/>
++  <feature name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml
+index a7f4fa3f01..f4d92cf034 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml
+@@ -5,4 +5,5 @@
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c2300c' edx='0x08000000'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
+   <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x000014f6'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-enabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-enabled.xml
+index 772456f947..910491c7f6 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-enabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-enabled.xml
+@@ -6,4 +6,5 @@
+   <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000007' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x000003f3' edx='0x26500800'/>
+   <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00001000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml
+index 96fdea306f..9164987bbd 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml
+@@ -15,5 +15,15 @@
+   <feature policy='require' name='invtsc'/>
+   <feature policy='require' name='clzero'/>
+   <feature policy='require' name='xsaveerptr'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='lbrv'/>
++  <feature policy='require' name='svm-lock'/>
++  <feature policy='require' name='nrip-save'/>
++  <feature policy='require' name='tsc-scale'/>
++  <feature policy='require' name='vmcb-clean'/>
++  <feature policy='require' name='flushbyasid'/>
++  <feature policy='require' name='decodeassists'/>
++  <feature policy='require' name='pause-filter'/>
++  <feature policy='require' name='pfthreshold'/>
+   <feature policy='disable' name='rdtscp'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml
+index 4fff74f3aa..2fa8861e44 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml
+@@ -16,4 +16,14 @@
+   <feature name='invtsc'/>
+   <feature name='clzero'/>
+   <feature name='xsaveerptr'/>
++  <feature name='npt'/>
++  <feature name='lbrv'/>
++  <feature name='svm-lock'/>
++  <feature name='nrip-save'/>
++  <feature name='tsc-scale'/>
++  <feature name='vmcb-clean'/>
++  <feature name='flushbyasid'/>
++  <feature name='decodeassists'/>
++  <feature name='pause-filter'/>
++  <feature name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-json.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-json.xml
+index c4e34a0fa1..af1e7f2f32 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-json.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-json.xml
+@@ -6,6 +6,8 @@
+   <feature policy='require' name='hypervisor'/>
+   <feature policy='require' name='tsc_adjust'/>
+   <feature policy='require' name='cmp_legacy'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='nrip-save'/>
+   <feature policy='disable' name='monitor'/>
+   <feature policy='disable' name='rdtscp'/>
+   <feature policy='disable' name='svm'/>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-json.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-json.xml
+index 7bf2d1b852..4450a40f61 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-json.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-json.xml
+@@ -6,6 +6,8 @@
+   <feature policy='require' name='hypervisor'/>
+   <feature policy='require' name='tsc_adjust'/>
+   <feature policy='require' name='cmp_legacy'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='nrip-save'/>
+   <feature policy='disable' name='monitor'/>
+   <feature policy='disable' name='svm'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-FX-8150-guest.xml b/tests/cputestdata/x86_64-cpuid-FX-8150-guest.xml
+index 6bd032bbcb..ee34ea8547 100644
+--- a/tests/cputestdata/x86_64-cpuid-FX-8150-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-FX-8150-guest.xml
+@@ -20,4 +20,14 @@
+   <feature policy='require' name='perfctr_core'/>
+   <feature policy='require' name='perfctr_nb'/>
+   <feature policy='require' name='invtsc'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='lbrv'/>
++  <feature policy='require' name='svm-lock'/>
++  <feature policy='require' name='nrip-save'/>
++  <feature policy='require' name='tsc-scale'/>
++  <feature policy='require' name='vmcb-clean'/>
++  <feature policy='require' name='flushbyasid'/>
++  <feature policy='require' name='decodeassists'/>
++  <feature policy='require' name='pause-filter'/>
++  <feature policy='require' name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-FX-8150-host.xml b/tests/cputestdata/x86_64-cpuid-FX-8150-host.xml
+index ec670c612e..75595c02af 100644
+--- a/tests/cputestdata/x86_64-cpuid-FX-8150-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-FX-8150-host.xml
+@@ -21,4 +21,14 @@
+   <feature name='perfctr_core'/>
+   <feature name='perfctr_nb'/>
+   <feature name='invtsc'/>
++  <feature name='npt'/>
++  <feature name='lbrv'/>
++  <feature name='svm-lock'/>
++  <feature name='nrip-save'/>
++  <feature name='tsc-scale'/>
++  <feature name='vmcb-clean'/>
++  <feature name='flushbyasid'/>
++  <feature name='decodeassists'/>
++  <feature name='pause-filter'/>
++  <feature name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml
+index c26c9c7be3..25ef2d3314 100644
+--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml
+@@ -5,4 +5,5 @@
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c2300c' edx='0x00000000'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
+   <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x000014f6'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-enabled.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-enabled.xml
+index fcefcf73c8..9181c3a9fe 100644
+--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-enabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-enabled.xml
+@@ -6,4 +6,5 @@
+   <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000007' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x000003f3' edx='0x2e500800'/>
+   <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml
+index 844b8b9d4f..08c574255e 100644
+--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml
+@@ -15,4 +15,14 @@
+   <feature policy='require' name='invtsc'/>
+   <feature policy='require' name='clzero'/>
+   <feature policy='require' name='xsaveerptr'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='lbrv'/>
++  <feature policy='require' name='svm-lock'/>
++  <feature policy='require' name='nrip-save'/>
++  <feature policy='require' name='tsc-scale'/>
++  <feature policy='require' name='vmcb-clean'/>
++  <feature policy='require' name='flushbyasid'/>
++  <feature policy='require' name='decodeassists'/>
++  <feature policy='require' name='pause-filter'/>
++  <feature policy='require' name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml
+index 3d1b143eba..f1cddb6a19 100644
+--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml
+@@ -16,4 +16,14 @@
+   <feature name='invtsc'/>
+   <feature name='clzero'/>
+   <feature name='xsaveerptr'/>
++  <feature name='npt'/>
++  <feature name='lbrv'/>
++  <feature name='svm-lock'/>
++  <feature name='nrip-save'/>
++  <feature name='tsc-scale'/>
++  <feature name='vmcb-clean'/>
++  <feature name='flushbyasid'/>
++  <feature name='decodeassists'/>
++  <feature name='pause-filter'/>
++  <feature name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-json.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-json.xml
+index d3003b6965..0fdd934c08 100644
+--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-json.xml
++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-json.xml
+@@ -7,6 +7,8 @@
+   <feature policy='require' name='tsc_adjust'/>
+   <feature policy='require' name='cmp_legacy'/>
+   <feature policy='require' name='virt-ssbd'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='nrip-save'/>
+   <feature policy='disable' name='monitor'/>
+   <feature policy='disable' name='svm'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-1352-guest.xml b/tests/cputestdata/x86_64-cpuid-Opteron-1352-guest.xml
+index 652f1e4333..a52c4cd303 100644
+--- a/tests/cputestdata/x86_64-cpuid-Opteron-1352-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-Opteron-1352-guest.xml
+@@ -15,4 +15,7 @@
+   <feature policy='require' name='osvw'/>
+   <feature policy='require' name='ibs'/>
+   <feature policy='require' name='invtsc'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='lbrv'/>
++  <feature policy='require' name='svm-lock'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-1352-host.xml b/tests/cputestdata/x86_64-cpuid-Opteron-1352-host.xml
+index 399398eb3a..800b092f14 100644
+--- a/tests/cputestdata/x86_64-cpuid-Opteron-1352-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-Opteron-1352-host.xml
+@@ -16,4 +16,7 @@
+   <feature name='osvw'/>
+   <feature name='ibs'/>
+   <feature name='invtsc'/>
++  <feature name='npt'/>
++  <feature name='lbrv'/>
++  <feature name='svm-lock'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-2350-disabled.xml b/tests/cputestdata/x86_64-cpuid-Opteron-2350-disabled.xml
+index 8ec1b12582..3f6fe54055 100644
+--- a/tests/cputestdata/x86_64-cpuid-Opteron-2350-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Opteron-2350-disabled.xml
+@@ -3,4 +3,5 @@
+   <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000008' edx='0x10000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000408' edx='0x08000000'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-2350-enabled.xml b/tests/cputestdata/x86_64-cpuid-Opteron-2350-enabled.xml
+index 913980f15f..5fd0d6066d 100644
+--- a/tests/cputestdata/x86_64-cpuid-Opteron-2350-enabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Opteron-2350-enabled.xml
+@@ -2,4 +2,5 @@
+ <cpudata arch='x86'>
+   <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x81a02001' edx='0x078bfbff'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x000003f7' edx='0xe6500800'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000001'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-2350-guest.xml b/tests/cputestdata/x86_64-cpuid-Opteron-2350-guest.xml
+index 652f1e4333..a52c4cd303 100644
+--- a/tests/cputestdata/x86_64-cpuid-Opteron-2350-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-Opteron-2350-guest.xml
+@@ -15,4 +15,7 @@
+   <feature policy='require' name='osvw'/>
+   <feature policy='require' name='ibs'/>
+   <feature policy='require' name='invtsc'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='lbrv'/>
++  <feature policy='require' name='svm-lock'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-2350-host.xml b/tests/cputestdata/x86_64-cpuid-Opteron-2350-host.xml
+index 399398eb3a..800b092f14 100644
+--- a/tests/cputestdata/x86_64-cpuid-Opteron-2350-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-Opteron-2350-host.xml
+@@ -16,4 +16,7 @@
+   <feature name='osvw'/>
+   <feature name='ibs'/>
+   <feature name='invtsc'/>
++  <feature name='npt'/>
++  <feature name='lbrv'/>
++  <feature name='svm-lock'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-2350-json.xml b/tests/cputestdata/x86_64-cpuid-Opteron-2350-json.xml
+index 741757aeb2..d128553c13 100644
+--- a/tests/cputestdata/x86_64-cpuid-Opteron-2350-json.xml
++++ b/tests/cputestdata/x86_64-cpuid-Opteron-2350-json.xml
+@@ -14,6 +14,7 @@
+   <feature policy='require' name='cr8legacy'/>
+   <feature policy='require' name='3dnowprefetch'/>
+   <feature policy='require' name='osvw'/>
++  <feature policy='require' name='npt'/>
+   <feature policy='disable' name='monitor'/>
+   <feature policy='disable' name='rdtscp'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6234-disabled.xml b/tests/cputestdata/x86_64-cpuid-Opteron-6234-disabled.xml
+index 88124d1745..4dcd74103b 100644
+--- a/tests/cputestdata/x86_64-cpuid-Opteron-6234-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6234-disabled.xml
+@@ -3,4 +3,5 @@
+   <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x08000008' edx='0x10000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c8b40c' edx='0x08000000'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x000014f6'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6234-enabled.xml b/tests/cputestdata/x86_64-cpuid-Opteron-6234-enabled.xml
+index 38d716449d..890b5df060 100644
+--- a/tests/cputestdata/x86_64-cpuid-Opteron-6234-enabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6234-enabled.xml
+@@ -4,4 +4,5 @@
+   <cpuid eax_in='0x00000006' ecx_in='0x00' eax='0x00000004' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000002' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00010bf3' edx='0x26500800'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6234-guest.xml b/tests/cputestdata/x86_64-cpuid-Opteron-6234-guest.xml
+index 6bd032bbcb..ee34ea8547 100644
+--- a/tests/cputestdata/x86_64-cpuid-Opteron-6234-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6234-guest.xml
+@@ -20,4 +20,14 @@
+   <feature policy='require' name='perfctr_core'/>
+   <feature policy='require' name='perfctr_nb'/>
+   <feature policy='require' name='invtsc'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='lbrv'/>
++  <feature policy='require' name='svm-lock'/>
++  <feature policy='require' name='nrip-save'/>
++  <feature policy='require' name='tsc-scale'/>
++  <feature policy='require' name='vmcb-clean'/>
++  <feature policy='require' name='flushbyasid'/>
++  <feature policy='require' name='decodeassists'/>
++  <feature policy='require' name='pause-filter'/>
++  <feature policy='require' name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6234-host.xml b/tests/cputestdata/x86_64-cpuid-Opteron-6234-host.xml
+index ec670c612e..75595c02af 100644
+--- a/tests/cputestdata/x86_64-cpuid-Opteron-6234-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6234-host.xml
+@@ -21,4 +21,14 @@
+   <feature name='perfctr_core'/>
+   <feature name='perfctr_nb'/>
+   <feature name='invtsc'/>
++  <feature name='npt'/>
++  <feature name='lbrv'/>
++  <feature name='svm-lock'/>
++  <feature name='nrip-save'/>
++  <feature name='tsc-scale'/>
++  <feature name='vmcb-clean'/>
++  <feature name='flushbyasid'/>
++  <feature name='decodeassists'/>
++  <feature name='pause-filter'/>
++  <feature name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6234-json.xml b/tests/cputestdata/x86_64-cpuid-Opteron-6234-json.xml
+index 2ad3c98a5a..abfc8db290 100644
+--- a/tests/cputestdata/x86_64-cpuid-Opteron-6234-json.xml
++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6234-json.xml
+@@ -12,6 +12,8 @@
+   <feature policy='require' name='cmp_legacy'/>
+   <feature policy='require' name='cr8legacy'/>
+   <feature policy='require' name='osvw'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='nrip-save'/>
+   <feature policy='disable' name='rdtscp'/>
+   <feature policy='disable' name='svm'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6282-guest.xml b/tests/cputestdata/x86_64-cpuid-Opteron-6282-guest.xml
+index 6bd032bbcb..ee34ea8547 100644
+--- a/tests/cputestdata/x86_64-cpuid-Opteron-6282-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6282-guest.xml
+@@ -20,4 +20,14 @@
+   <feature policy='require' name='perfctr_core'/>
+   <feature policy='require' name='perfctr_nb'/>
+   <feature policy='require' name='invtsc'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='lbrv'/>
++  <feature policy='require' name='svm-lock'/>
++  <feature policy='require' name='nrip-save'/>
++  <feature policy='require' name='tsc-scale'/>
++  <feature policy='require' name='vmcb-clean'/>
++  <feature policy='require' name='flushbyasid'/>
++  <feature policy='require' name='decodeassists'/>
++  <feature policy='require' name='pause-filter'/>
++  <feature policy='require' name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6282-host.xml b/tests/cputestdata/x86_64-cpuid-Opteron-6282-host.xml
+index ec670c612e..75595c02af 100644
+--- a/tests/cputestdata/x86_64-cpuid-Opteron-6282-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6282-host.xml
+@@ -21,4 +21,14 @@
+   <feature name='perfctr_core'/>
+   <feature name='perfctr_nb'/>
+   <feature name='invtsc'/>
++  <feature name='npt'/>
++  <feature name='lbrv'/>
++  <feature name='svm-lock'/>
++  <feature name='nrip-save'/>
++  <feature name='tsc-scale'/>
++  <feature name='vmcb-clean'/>
++  <feature name='flushbyasid'/>
++  <feature name='decodeassists'/>
++  <feature name='pause-filter'/>
++  <feature name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Phenom-B95-disabled.xml b/tests/cputestdata/x86_64-cpuid-Phenom-B95-disabled.xml
+index d8d4e8a5f9..3910eb6e57 100644
+--- a/tests/cputestdata/x86_64-cpuid-Phenom-B95-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Phenom-B95-disabled.xml
+@@ -3,4 +3,5 @@
+   <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000008' edx='0x10000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x0000340c' edx='0x08000000'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Phenom-B95-enabled.xml b/tests/cputestdata/x86_64-cpuid-Phenom-B95-enabled.xml
+index d15e625087..2a090a04d8 100644
+--- a/tests/cputestdata/x86_64-cpuid-Phenom-B95-enabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Phenom-B95-enabled.xml
+@@ -2,4 +2,5 @@
+ <cpudata arch='x86'>
+   <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x80a02001' edx='0x078bfbff'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x000003f3' edx='0xe6400800'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Phenom-B95-guest.xml b/tests/cputestdata/x86_64-cpuid-Phenom-B95-guest.xml
+index d7a06108bc..ab0e99f97d 100644
+--- a/tests/cputestdata/x86_64-cpuid-Phenom-B95-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-Phenom-B95-guest.xml
+@@ -17,5 +17,9 @@
+   <feature policy='require' name='skinit'/>
+   <feature policy='require' name='wdt'/>
+   <feature policy='require' name='invtsc'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='lbrv'/>
++  <feature policy='require' name='svm-lock'/>
++  <feature policy='require' name='nrip-save'/>
+   <feature policy='disable' name='nx'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Phenom-B95-host.xml b/tests/cputestdata/x86_64-cpuid-Phenom-B95-host.xml
+index 127b047854..95875918c9 100644
+--- a/tests/cputestdata/x86_64-cpuid-Phenom-B95-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-Phenom-B95-host.xml
+@@ -28,4 +28,8 @@
+   <feature name='skinit'/>
+   <feature name='wdt'/>
+   <feature name='invtsc'/>
++  <feature name='npt'/>
++  <feature name='lbrv'/>
++  <feature name='svm-lock'/>
++  <feature name='nrip-save'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Phenom-B95-json.xml b/tests/cputestdata/x86_64-cpuid-Phenom-B95-json.xml
+index 7ce56ac8e7..d161709981 100644
+--- a/tests/cputestdata/x86_64-cpuid-Phenom-B95-json.xml
++++ b/tests/cputestdata/x86_64-cpuid-Phenom-B95-json.xml
+@@ -13,6 +13,8 @@
+   <feature policy='require' name='cr8legacy'/>
+   <feature policy='require' name='3dnowprefetch'/>
+   <feature policy='require' name='osvw'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='nrip-save'/>
+   <feature policy='disable' name='monitor'/>
+   <feature policy='disable' name='nx'/>
+   <feature policy='disable' name='rdtscp'/>
+diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml
+index 0358ecf478..a63cd5c4b4 100644
+--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml
+@@ -6,4 +6,5 @@
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c23008' edx='0x00000000'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
+   <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x000014f6'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-enabled.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-enabled.xml
+index a212679fba..f1a0ad3315 100644
+--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-enabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-enabled.xml
+@@ -5,4 +5,5 @@
+   <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x009c01ab' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000007' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x000003f7' edx='0x2e500800'/>
++  <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml
+index 612e571609..0053913327 100644
+--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml
+@@ -15,4 +15,14 @@
+   <feature policy='require' name='invtsc'/>
+   <feature policy='require' name='clzero'/>
+   <feature policy='require' name='xsaveerptr'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='lbrv'/>
++  <feature policy='require' name='svm-lock'/>
++  <feature policy='require' name='nrip-save'/>
++  <feature policy='require' name='tsc-scale'/>
++  <feature policy='require' name='vmcb-clean'/>
++  <feature policy='require' name='flushbyasid'/>
++  <feature policy='require' name='decodeassists'/>
++  <feature policy='require' name='pause-filter'/>
++  <feature policy='require' name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml
+index 7498d924e2..7acab0a999 100644
+--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml
+@@ -16,4 +16,14 @@
+   <feature name='invtsc'/>
+   <feature name='clzero'/>
+   <feature name='xsaveerptr'/>
++  <feature name='npt'/>
++  <feature name='lbrv'/>
++  <feature name='svm-lock'/>
++  <feature name='nrip-save'/>
++  <feature name='tsc-scale'/>
++  <feature name='vmcb-clean'/>
++  <feature name='flushbyasid'/>
++  <feature name='decodeassists'/>
++  <feature name='pause-filter'/>
++  <feature name='pfthreshold'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-json.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-json.xml
+index 32064548c7..aecc335c1e 100644
+--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-json.xml
++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-json.xml
+@@ -6,6 +6,8 @@
+   <feature policy='require' name='hypervisor'/>
+   <feature policy='require' name='tsc_adjust'/>
+   <feature policy='require' name='cmp_legacy'/>
++  <feature policy='require' name='npt'/>
++  <feature policy='require' name='nrip-save'/>
+   <feature policy='disable' name='monitor'/>
+   <feature policy='disable' name='sha-ni'/>
+ </cpu>
+diff --git a/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml
+index d369fa827a..d3211e7a13 100644
+--- a/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml
++++ b/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml
+@@ -43,6 +43,7 @@
+       <feature policy='require' name='la57'/>
+       <feature policy='require' name='3dnowext'/>
+       <feature policy='require' name='3dnow'/>
++      <feature policy='require' name='npt'/>
+       <feature policy='disable' name='vme'/>
+       <feature policy='disable' name='fma'/>
+       <feature policy='disable' name='avx'/>
+diff --git a/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml
+index 444d90504e..756b28034e 100644
+--- a/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml
++++ b/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml
+@@ -43,6 +43,7 @@
+       <feature policy='require' name='la57'/>
+       <feature policy='require' name='3dnowext'/>
+       <feature policy='require' name='3dnow'/>
++      <feature policy='require' name='npt'/>
+       <feature policy='disable' name='vme'/>
+       <feature policy='disable' name='fma'/>
+       <feature policy='disable' name='avx'/>
+diff --git a/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml
+index 463f0db390..0aa8aa18be 100644
+--- a/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml
++++ b/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml
+@@ -43,6 +43,7 @@
+       <feature policy='require' name='la57'/>
+       <feature policy='require' name='3dnowext'/>
+       <feature policy='require' name='3dnow'/>
++      <feature policy='require' name='npt'/>
+       <feature policy='disable' name='vme'/>
+       <feature policy='disable' name='fma'/>
+       <feature policy='disable' name='avx'/>
+@@ -57,6 +58,7 @@
+       <feature policy='disable' name='3dnowprefetch'/>
+       <feature policy='disable' name='osvw'/>
+       <feature policy='disable' name='topoext'/>
++      <feature policy='disable' name='nrip-save'/>
+     </mode>
+     <mode name='custom' supported='yes'>
+       <model usable='yes'>qemu64</model>
+diff --git a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml
+index 5bfd065986..d6265ce243 100644
+--- a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml
++++ b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml
+@@ -43,6 +43,7 @@
+       <feature policy='require' name='la57'/>
+       <feature policy='require' name='3dnowext'/>
+       <feature policy='require' name='3dnow'/>
++      <feature policy='require' name='npt'/>
+       <feature policy='disable' name='vme'/>
+       <feature policy='disable' name='fma'/>
+       <feature policy='disable' name='avx'/>
+@@ -57,6 +58,7 @@
+       <feature policy='disable' name='osvw'/>
+       <feature policy='disable' name='topoext'/>
+       <feature policy='disable' name='ibpb'/>
++      <feature policy='disable' name='nrip-save'/>
+     </mode>
+     <mode name='custom' supported='yes'>
+       <model usable='yes'>qemu64</model>
+diff --git a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml
+index c762b0b600..bcaf9afd6f 100644
+--- a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml
++++ b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml
+@@ -43,6 +43,7 @@
+       <feature policy='require' name='la57'/>
+       <feature policy='require' name='3dnowext'/>
+       <feature policy='require' name='3dnow'/>
++      <feature policy='require' name='npt'/>
+       <feature policy='disable' name='vme'/>
+       <feature policy='disable' name='fma'/>
+       <feature policy='disable' name='avx'/>
+@@ -57,6 +58,7 @@
+       <feature policy='disable' name='osvw'/>
+       <feature policy='disable' name='topoext'/>
+       <feature policy='disable' name='ibpb'/>
++      <feature policy='disable' name='nrip-save'/>
+     </mode>
+     <mode name='custom' supported='yes'>
+       <model usable='yes'>qemu64</model>
+diff --git a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml
+index 0a4bb16a89..eb456dea28 100644
+--- a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml
++++ b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml
+@@ -43,6 +43,7 @@
+       <feature policy='require' name='la57'/>
+       <feature policy='require' name='3dnowext'/>
+       <feature policy='require' name='3dnow'/>
++      <feature policy='require' name='npt'/>
+       <feature policy='disable' name='vme'/>
+       <feature policy='disable' name='fma'/>
+       <feature policy='disable' name='avx'/>
+@@ -56,6 +57,7 @@
+       <feature policy='disable' name='3dnowprefetch'/>
+       <feature policy='disable' name='osvw'/>
+       <feature policy='disable' name='topoext'/>
++      <feature policy='disable' name='nrip-save'/>
+     </mode>
+     <mode name='custom' supported='yes'>
+       <model usable='yes'>qemu64</model>
+diff --git a/tests/qemuxml2argvdata/cpu-host-model-cmt.x86_64-4.0.0.args b/tests/qemuxml2argvdata/cpu-host-model-cmt.x86_64-4.0.0.args
+index b44dc2ec48..6ee7bed18e 100644
+--- a/tests/qemuxml2argvdata/cpu-host-model-cmt.x86_64-4.0.0.args
++++ b/tests/qemuxml2argvdata/cpu-host-model-cmt.x86_64-4.0.0.args
+@@ -14,9 +14,9 @@ QEMU_AUDIO_DRV=none \
+ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+ -machine pc-i440fx-4.0,accel=tcg,usb=off,dump-guest-core=off \
+ -cpu EPYC,acpi=on,ss=on,hypervisor=on,erms=on,mpx=on,pcommit=on,clwb=on,pku=on,\
+-la57=on,3dnowext=on,3dnow=on,vme=off,fma=off,avx=off,f16c=off,rdrand=off,\
+-avx2=off,rdseed=off,sha-ni=off,xsavec=off,fxsr_opt=off,misalignsse=off,\
+-3dnowprefetch=off,osvw=off,topoext=off \
++la57=on,3dnowext=on,3dnow=on,npt=on,vme=off,fma=off,avx=off,f16c=off,\
++rdrand=off,avx2=off,rdseed=off,sha-ni=off,xsavec=off,fxsr_opt=off,\
++misalignsse=off,3dnowprefetch=off,osvw=off,topoext=off,nrip-save=off \
+ -m 214 \
+ -overcommit mem-lock=off \
+ -smp 6,sockets=6,cores=1,threads=1 \
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-cpu_map-Add-missing-x86-features-in-0x7-CPUID-leaf.patch b/SOURCES/libvirt-cpu_map-Add-missing-x86-features-in-0x7-CPUID-leaf.patch
new file mode 100644
index 0000000..42bfd9e
--- /dev/null
+++ b/SOURCES/libvirt-cpu_map-Add-missing-x86-features-in-0x7-CPUID-leaf.patch
@@ -0,0 +1,107 @@
+From cff220056e78bad15a8addf9739f8a556b7a6ea2 Mon Sep 17 00:00:00 2001
+Message-Id: <cff220056e78bad15a8addf9739f8a556b7a6ea2@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Thu, 8 Oct 2020 18:01:21 +0200
+Subject: [PATCH] cpu_map: Add missing x86 features in 0x7 CPUID leaf
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 6ea3bb19c6fed39429c95eb284487b849cb12e2a)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1861506
+
+Conflicts:
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-enabled.xml
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-guest.xml
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-host.xml
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-json.xml
+	tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml
+	tests/domaincapsdata/qemu_5.1.0.x86_64.xml
+            - not present downstream
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Message-Id: <04da640b0fbbbcec9be63e552a3029f983bf879a.1602172344.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/cpu_map/x86_features.xml                         | 12 ++++++++++++
+ .../x86_64-cpuid-Ice-Lake-Server-disabled.xml        |  2 +-
+ .../x86_64-cpuid-Ice-Lake-Server-guest.xml           |  1 +
+ .../x86_64-cpuid-Ice-Lake-Server-host.xml            |  1 +
+ 4 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml
+index 8525ae0fa5..364e45fb32 100644
+--- a/src/cpu_map/x86_features.xml
++++ b/src/cpu_map/x86_features.xml
+@@ -286,6 +286,9 @@
+   <feature name='ospke'>
+     <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x00000010'/>
+   </feature>
++  <feature name='waitpkg'>
++    <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x00000020'/>
++  </feature>
+   <feature name='avx512vbmi2'>
+     <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x00000040'/>
+   </feature>
+@@ -310,9 +313,18 @@
+   <feature name='la57'>
+     <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x00010000'/>
+   </feature>
++  <feature name='rdpid'>
++    <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x00400000'/>
++  </feature>
+   <feature name='cldemote'>
+     <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x02000000'/>
+   </feature>
++  <feature name='movdiri'>
++    <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x08000000'/>
++  </feature>
++  <feature name='movdir64b'>
++    <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x10000000'/>
++  </feature>
+ 
+   <feature name='avx512-4vnniw'>
+     <cpuid eax_in='0x07' ecx_in='0x00' edx='0x00000004'/>
+diff --git a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml
+index 62c6bad612..ce65579bcc 100644
+--- a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml
+@@ -1,7 +1,7 @@
+ <!-- Features disabled by QEMU -->
+ <cpudata arch='x86'>
+   <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x0804c1fc' edx='0xb0600000'/>
+-  <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00000010' edx='0x00000000'/>
++  <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00400010' edx='0x00000000'/>
+   <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml
+index 4676f3aa7d..9b75ace710 100644
+--- a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml
+@@ -23,6 +23,7 @@
+   <feature policy='require' name='avx512ifma'/>
+   <feature policy='require' name='sha-ni'/>
+   <feature policy='require' name='ospke'/>
++  <feature policy='require' name='rdpid'/>
+   <feature policy='require' name='stibp'/>
+   <feature policy='require' name='arch-capabilities'/>
+   <feature policy='require' name='xsaves'/>
+diff --git a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml
+index 35b9e39629..efbf9d363b 100644
+--- a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml
+@@ -24,6 +24,7 @@
+   <feature name='avx512ifma'/>
+   <feature name='sha-ni'/>
+   <feature name='ospke'/>
++  <feature name='rdpid'/>
+   <feature name='stibp'/>
+   <feature name='arch-capabilities'/>
+   <feature name='xsaves'/>
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-cpu_map-Add-missing-x86-features-in-0x80000008-CPUID-leaf.patch b/SOURCES/libvirt-cpu_map-Add-missing-x86-features-in-0x80000008-CPUID-leaf.patch
new file mode 100644
index 0000000..b7020fc
--- /dev/null
+++ b/SOURCES/libvirt-cpu_map-Add-missing-x86-features-in-0x80000008-CPUID-leaf.patch
@@ -0,0 +1,224 @@
+From 1d6a30efa98fc0cf39725792efae1a151797589f Mon Sep 17 00:00:00 2001
+Message-Id: <1d6a30efa98fc0cf39725792efae1a151797589f@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Thu, 8 Oct 2020 18:01:22 +0200
+Subject: [PATCH] cpu_map: Add missing x86 features in 0x80000008 CPUID leaf
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+(cherry picked from commit 892b7c70f66abc511e1251382c9183493024f253)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1861506
+
+Conflicts:
+	tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml
+	tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml
+	tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml
+	tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml
+            - commit df69263c26 (cpu_map: Request test files update when
+              adding x86 features) not backported
+
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-disabled.xml
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-enabled.xml
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-guest.xml
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-host.xml
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-json.xml
+	tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml
+	tests/domaincapsdata/qemu_5.1.0.x86_64.xml
+            - not present downstream
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Message-Id: <27effeb5e12252982411796bd72e078d3afe49cb.1602172344.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/cpu_map/x86_features.xml                                | 6 ++++++
+ tests/cputestdata/x86_64-cpuid-Cooperlake-enabled.xml       | 2 +-
+ tests/cputestdata/x86_64-cpuid-Cooperlake-json.xml          | 1 +
+ .../cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml | 1 +
+ tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml  | 1 +
+ tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml   | 1 +
+ .../x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml        | 1 +
+ .../x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml           | 1 +
+ .../x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml            | 1 +
+ .../x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml        | 1 +
+ .../x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml           | 1 +
+ .../x86_64-cpuid-Hygon-C86-7185-32-core-host.xml            | 1 +
+ .../x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml      | 1 +
+ .../x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml         | 1 +
+ .../x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml          | 1 +
+ 15 files changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml
+index 364e45fb32..5265b2989b 100644
+--- a/src/cpu_map/x86_features.xml
++++ b/src/cpu_map/x86_features.xml
+@@ -486,12 +486,18 @@
+   <feature name='clzero'>
+     <cpuid eax_in='0x80000008' ebx='0x00000001'/>
+   </feature>
++  <feature name='xsaveerptr'>
++    <cpuid eax_in='0x80000008' ebx='0x00000004'/>
++  </feature>
+   <feature name='wbnoinvd'>
+     <cpuid eax_in='0x80000008' ebx='0x00000200'/>
+   </feature>
+   <feature name='ibpb'>
+     <cpuid eax_in='0x80000008' ebx='0x00001000'/>
+   </feature>
++  <feature name='amd-stibp'>
++    <cpuid eax_in='0x80000008' ebx='0x00008000'/>
++  </feature>
+   <feature name='amd-ssbd'>
+     <cpuid eax_in='0x80000008' ebx='0x01000000'/>
+   </feature>
+diff --git a/tests/cputestdata/x86_64-cpuid-Cooperlake-enabled.xml b/tests/cputestdata/x86_64-cpuid-Cooperlake-enabled.xml
+index 2d7f83c80f..1d91c3efa8 100644
+--- a/tests/cputestdata/x86_64-cpuid-Cooperlake-enabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Cooperlake-enabled.xml
+@@ -6,6 +6,6 @@
+   <cpuid eax_in='0x00000007' ecx_in='0x01' eax='0x00000020' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x0000000f' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000121' edx='0x2c100800'/>
+-  <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x01001000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x01009000' ecx='0x00000000' edx='0x00000000'/>
+   <msr index='0x10a' edx='0x00000000' eax='0x000001eb'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Cooperlake-json.xml b/tests/cputestdata/x86_64-cpuid-Cooperlake-json.xml
+index fb319d547c..c89e0e5350 100644
+--- a/tests/cputestdata/x86_64-cpuid-Cooperlake-json.xml
++++ b/tests/cputestdata/x86_64-cpuid-Cooperlake-json.xml
+@@ -10,6 +10,7 @@
+   <feature policy='require' name='md-clear'/>
+   <feature policy='require' name='xsaves'/>
+   <feature policy='require' name='ibpb'/>
++  <feature policy='require' name='amd-stibp'/>
+   <feature policy='require' name='amd-ssbd'/>
+   <feature policy='require' name='tsx-ctrl'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml
+index 747d725acf..c26c9c7be3 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml
+@@ -4,4 +4,5 @@
+   <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000008' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c2300c' edx='0x00000000'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
++  <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml
+index b75196aac5..612e571609 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml
+@@ -14,4 +14,5 @@
+   <feature policy='require' name='perfctr_nb'/>
+   <feature policy='require' name='invtsc'/>
+   <feature policy='require' name='clzero'/>
++  <feature policy='require' name='xsaveerptr'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml
+index fd84b526db..7498d924e2 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml
+@@ -15,4 +15,5 @@
+   <feature name='perfctr_nb'/>
+   <feature name='invtsc'/>
+   <feature name='clzero'/>
++  <feature name='xsaveerptr'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml
+index af43fca98d..a7f4fa3f01 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml
+@@ -4,4 +4,5 @@
+   <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000008' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c2300c' edx='0x08000000'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
++  <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml
+index 5044c8cc35..96fdea306f 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml
+@@ -14,5 +14,6 @@
+   <feature policy='require' name='perfctr_nb'/>
+   <feature policy='require' name='invtsc'/>
+   <feature policy='require' name='clzero'/>
++  <feature policy='require' name='xsaveerptr'/>
+   <feature policy='disable' name='rdtscp'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml
+index d7d5ce88d9..4fff74f3aa 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml
+@@ -15,4 +15,5 @@
+   <feature name='perfctr_nb'/>
+   <feature name='invtsc'/>
+   <feature name='clzero'/>
++  <feature name='xsaveerptr'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml
+index 747d725acf..c26c9c7be3 100644
+--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml
+@@ -4,4 +4,5 @@
+   <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000008' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c2300c' edx='0x00000000'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
++  <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml
+index 75c71233c6..844b8b9d4f 100644
+--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml
+@@ -14,4 +14,5 @@
+   <feature policy='require' name='perfctr_nb'/>
+   <feature policy='require' name='invtsc'/>
+   <feature policy='require' name='clzero'/>
++  <feature policy='require' name='xsaveerptr'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml
+index 82f28067c4..3d1b143eba 100644
+--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml
+@@ -15,4 +15,5 @@
+   <feature name='perfctr_nb'/>
+   <feature name='invtsc'/>
+   <feature name='clzero'/>
++  <feature name='xsaveerptr'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml
+index b085050618..0358ecf478 100644
+--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml
+@@ -5,4 +5,5 @@
+   <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000008' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
+   <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c23008' edx='0x00000000'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
++  <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml
+index b75196aac5..612e571609 100644
+--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml
+@@ -14,4 +14,5 @@
+   <feature policy='require' name='perfctr_nb'/>
+   <feature policy='require' name='invtsc'/>
+   <feature policy='require' name='clzero'/>
++  <feature policy='require' name='xsaveerptr'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml
+index fd84b526db..7498d924e2 100644
+--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml
+@@ -15,4 +15,5 @@
+   <feature name='perfctr_nb'/>
+   <feature name='invtsc'/>
+   <feature name='clzero'/>
++  <feature name='xsaveerptr'/>
+ </cpu>
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-cpu_map-Add-support-for-core-capability-CPU-feature.patch b/SOURCES/libvirt-cpu_map-Add-support-for-core-capability-CPU-feature.patch
new file mode 100644
index 0000000..0140b50
--- /dev/null
+++ b/SOURCES/libvirt-cpu_map-Add-support-for-core-capability-CPU-feature.patch
@@ -0,0 +1,76 @@
+From 287c112945dda0837c31348dc3c07ad7ed19596f Mon Sep 17 00:00:00 2001
+Message-Id: <287c112945dda0837c31348dc3c07ad7ed19596f@dist-git>
+From: Tim Wiederhake <twiederh@redhat.com>
+Date: Fri, 15 Jan 2021 15:17:20 +0100
+Subject: [PATCH] cpu_map: Add support for core-capability CPU feature
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit e06dd56032acf904da1aedfc097fa0cae7cb0b0f)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1537734
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Message-Id: <20210115141722.14986-5-twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/cpu_map/x86_features.xml                           | 3 +++
+ tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml | 2 +-
+ tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml    | 1 +
+ tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml     | 1 +
+ 4 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml
+index 70e1c7b3fc..f8c0b9046c 100644
+--- a/src/cpu_map/x86_features.xml
++++ b/src/cpu_map/x86_features.xml
+@@ -350,6 +350,9 @@
+   <feature name='arch-capabilities'> <!-- arch_capabilities, arch-facilities -->
+     <cpuid eax_in='0x07' ecx_in='0x00' edx='0x20000000'/>
+   </feature>
++  <feature name='core-capability'>
++    <cpuid eax_in='0x07' ecx_in='0x00' edx='0x40000000'/>
++  </feature>
+   <feature name='ssbd'>
+     <cpuid eax_in='0x07' ecx_in='0x00' edx='0x80000000'/>
+   </feature>
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml
+index 842c7b4a2a..50e8084140 100644
+--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml
+@@ -1,7 +1,7 @@
+ <!-- Features disabled by QEMU -->
+ <cpudata arch='x86'>
+   <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x080041dc' edx='0xb0600000'/>
+-  <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00000020' edx='0x00000000'/>
++  <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00000020' edx='0x40000000'/>
+   <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
+   <msr index='0x10a' edx='0x00000000' eax='0x00000100'/>
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml
+index 0f3e2e506e..4ad95f06b4 100644
+--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml
+@@ -37,6 +37,7 @@
+   <feature policy='require' name='md-clear'/>
+   <feature policy='require' name='stibp'/>
+   <feature policy='require' name='arch-capabilities'/>
++  <feature policy='require' name='core-capability'/>
+   <feature policy='require' name='ssbd'/>
+   <feature policy='require' name='xsaveopt'/>
+   <feature policy='require' name='xsavec'/>
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml
+index 3bd009c1da..cc2b208e6a 100644
+--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml
+@@ -47,6 +47,7 @@
+   <feature name='md-clear'/>
+   <feature name='stibp'/>
+   <feature name='arch-capabilities'/>
++  <feature name='core-capability'/>
+   <feature name='ssbd'/>
+   <feature name='xsaveopt'/>
+   <feature name='xsavec'/>
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-cpu_map-Add-support-for-fsrm-CPU-feature.patch b/SOURCES/libvirt-cpu_map-Add-support-for-fsrm-CPU-feature.patch
new file mode 100644
index 0000000..c6bd8ab
--- /dev/null
+++ b/SOURCES/libvirt-cpu_map-Add-support-for-fsrm-CPU-feature.patch
@@ -0,0 +1,76 @@
+From 7de3eaba72cecf596c732d12485e4f1a6115bf2f Mon Sep 17 00:00:00 2001
+Message-Id: <7de3eaba72cecf596c732d12485e4f1a6115bf2f@dist-git>
+From: Tim Wiederhake <twiederh@redhat.com>
+Date: Fri, 15 Jan 2021 15:17:19 +0100
+Subject: [PATCH] cpu_map: Add support for fsrm CPU feature
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit 8c5c660b99101544d8cfcb8edbe48688c04bee25)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1537734
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Message-Id: <20210115141722.14986-4-twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/cpu_map/x86_features.xml                                | 3 +++
+ tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml | 2 +-
+ tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml    | 1 +
+ tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml     | 1 +
+ 4 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml
+index 30d1375437..70e1c7b3fc 100644
+--- a/src/cpu_map/x86_features.xml
++++ b/src/cpu_map/x86_features.xml
+@@ -332,6 +332,9 @@
+   <feature name='avx512-4fmaps'>
+     <cpuid eax_in='0x07' ecx_in='0x00' edx='0x00000008'/>
+   </feature>
++  <feature name='fsrm'>
++    <cpuid eax_in='0x07' ecx_in='0x00' edx='0x00000010'/>
++  </feature>
+   <feature name='md-clear'> <!-- md_clear -->
+     <cpuid eax_in='0x07' ecx_in='0x00' edx='0x00000400'/>
+   </feature>
+diff --git a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml
+index ce65579bcc..33bd1013f0 100644
+--- a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml
+@@ -1,7 +1,7 @@
+ <!-- Features disabled by QEMU -->
+ <cpudata arch='x86'>
+   <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x0804c1fc' edx='0xb0600000'/>
+-  <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00400010' edx='0x00000000'/>
++  <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00400010' edx='0x00000010'/>
+   <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml
+index 9b75ace710..3a71b28cfb 100644
+--- a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml
+@@ -24,6 +24,7 @@
+   <feature policy='require' name='sha-ni'/>
+   <feature policy='require' name='ospke'/>
+   <feature policy='require' name='rdpid'/>
++  <feature policy='require' name='fsrm'/>
+   <feature policy='require' name='stibp'/>
+   <feature policy='require' name='arch-capabilities'/>
+   <feature policy='require' name='xsaves'/>
+diff --git a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml
+index efbf9d363b..1582de0422 100644
+--- a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml
+@@ -25,6 +25,7 @@
+   <feature name='sha-ni'/>
+   <feature name='ospke'/>
+   <feature name='rdpid'/>
++  <feature name='fsrm'/>
+   <feature name='stibp'/>
+   <feature name='arch-capabilities'/>
+   <feature name='xsaves'/>
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-cpu_map-Add-support-for-split-lock-detect-CPU-feature.patch b/SOURCES/libvirt-cpu_map-Add-support-for-split-lock-detect-CPU-feature.patch
new file mode 100644
index 0000000..9eee928
--- /dev/null
+++ b/SOURCES/libvirt-cpu_map-Add-support-for-split-lock-detect-CPU-feature.patch
@@ -0,0 +1,72 @@
+From 4b6dd39819e82b0775e0f324b0b4efa537882878 Mon Sep 17 00:00:00 2001
+Message-Id: <4b6dd39819e82b0775e0f324b0b4efa537882878@dist-git>
+From: Tim Wiederhake <twiederh@redhat.com>
+Date: Fri, 15 Jan 2021 15:17:21 +0100
+Subject: [PATCH] cpu_map: Add support for split-lock-detect CPU feature
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit 13db542cf3099f7955438e208dbe4b2b4e58067e)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1537734
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Message-Id: <20210115141722.14986-6-twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/cpu_map/x86_features.xml                           | 5 +++++
+ tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml | 1 +
+ tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml    | 1 +
+ tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml     | 1 +
+ 4 files changed, 8 insertions(+)
+
+diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml
+index f8c0b9046c..83d8e641a8 100644
+--- a/src/cpu_map/x86_features.xml
++++ b/src/cpu_map/x86_features.xml
+@@ -574,4 +574,9 @@
+   <feature name='taa-no'>
+     <msr index='0x10a' edx='0x00000000' eax='0x00000100'/>
+   </feature>
++
++  <!-- IA32_CORE_CAPABILITIES features -->
++  <feature name='split-lock-detect'>
++    <msr index='0xcf' edx='0x00000000' eax='0x00000020'/>
++  </feature>
+ </cpus>
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml
+index 50e8084140..81ffa7bfd3 100644
+--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml
+@@ -4,5 +4,6 @@
+   <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00000020' edx='0x40000000'/>
+   <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/>
+   <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
++  <msr index='0xcf' edx='0x00000000' eax='0x00000020'/>
+   <msr index='0x10a' edx='0x00000000' eax='0x00000100'/>
+ </cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml
+index 4ad95f06b4..2eeff136c4 100644
+--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml
+@@ -53,6 +53,7 @@
+   <feature policy='require' name='mds-no'/>
+   <feature policy='require' name='pschange-mc-no'/>
+   <feature policy='require' name='taa-no'/>
++  <feature policy='require' name='split-lock-detect'/>
+   <feature policy='disable' name='avx'/>
+   <feature policy='disable' name='f16c'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml
+index cc2b208e6a..b3e9d5c1ff 100644
+--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml
+@@ -64,4 +64,5 @@
+   <feature name='mds-no'/>
+   <feature name='pschange-mc-no'/>
+   <feature name='taa-no'/>
++  <feature name='split-lock-detect'/>
+ </cpu>
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-cpu_map-Define-and-enable-Snowridge-model.patch b/SOURCES/libvirt-cpu_map-Define-and-enable-Snowridge-model.patch
new file mode 100644
index 0000000..6a04845
--- /dev/null
+++ b/SOURCES/libvirt-cpu_map-Define-and-enable-Snowridge-model.patch
@@ -0,0 +1,373 @@
+From b177f66b37d0c64216ec579a5211461609a96ea8 Mon Sep 17 00:00:00 2001
+Message-Id: <b177f66b37d0c64216ec579a5211461609a96ea8@dist-git>
+From: Tim Wiederhake <twiederh@redhat.com>
+Date: Fri, 15 Jan 2021 15:17:22 +0100
+Subject: [PATCH] cpu_map: Define and enable Snowridge model
+
+Due to missing pdpe1gb support in the host CPU data, the CPU is still
+incorrectly detected as Westmere-IBRS for host capabilities because we
+don't have the option to disable features included in the base model
+there.
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit f0a5cf4b8a8b5a68348df5e8b197f30dd90b3c34)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1537734
+
+Conflicts:
+- src/cpu_map/index.xml: Context
+- src/cpu_map/meson.build: Not present downstream
+- tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml: Not present downstream
+- tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml: Not present downstream
+- tests/domaincapsdata/qemu_5.1.0.x86_64.xml: Not present downstream
+- tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml: Not present downstream
+- tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml: Not present downstream
+- tests/domaincapsdata/qemu_5.2.0.x86_64.xml: Not present downstream
+
+Additions:
+- src/cpu_map/Makefile.inc.am: Replaces upstream change of "meson.build"
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Message-Id: <20210115141722.14986-7-twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/cpu_map/Makefile.inc.am                   |  1 +
+ src/cpu_map/index.xml                         |  1 +
+ src/cpu_map/x86_Snowridge.xml                 | 71 +++++++++++++++++++
+ .../x86_64-cpuid-Atom-P5362-guest.xml         | 28 ++------
+ .../x86_64-cpuid-Atom-P5362-json.xml          | 26 ++-----
+ .../domaincapsdata/qemu_4.1.0-q35.x86_64.xml  |  1 +
+ .../domaincapsdata/qemu_4.1.0-tcg.x86_64.xml  |  1 +
+ tests/domaincapsdata/qemu_4.1.0.x86_64.xml    |  1 +
+ .../domaincapsdata/qemu_4.2.0-q35.x86_64.xml  |  1 +
+ .../domaincapsdata/qemu_4.2.0-tcg.x86_64.xml  |  1 +
+ tests/domaincapsdata/qemu_4.2.0.x86_64.xml    |  1 +
+ .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml  |  1 +
+ .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml  |  1 +
+ tests/domaincapsdata/qemu_5.0.0.x86_64.xml    |  1 +
+ 14 files changed, 92 insertions(+), 44 deletions(-)
+ create mode 100644 src/cpu_map/x86_Snowridge.xml
+
+diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am
+index aad4b410f9..1dd78c6715 100644
+--- a/src/cpu_map/Makefile.inc.am
++++ b/src/cpu_map/Makefile.inc.am
+@@ -67,6 +67,7 @@ cpumap_DATA = \
+ 	cpu_map/x86_Skylake-Server.xml \
+ 	cpu_map/x86_Skylake-Server-IBRS.xml \
+ 	cpu_map/x86_Skylake-Server-noTSX-IBRS.xml \
++	cpu_map/x86_Snowridge.xml \
+ 	cpu_map/x86_Westmere.xml \
+ 	cpu_map/x86_Westmere-IBRS.xml \
+ 	$(NULL)
+diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
+index 633b017a93..2f58261e6d 100644
+--- a/src/cpu_map/index.xml
++++ b/src/cpu_map/index.xml
+@@ -55,6 +55,7 @@
+     <include filename="x86_Icelake-Server.xml"/>
+     <include filename="x86_Icelake-Server-noTSX.xml"/>
+     <include filename="x86_Cooperlake.xml"/>
++    <include filename='x86_Snowridge.xml'/>
+ 
+     <!-- AMD CPUs -->
+     <include filename="x86_athlon.xml"/>
+diff --git a/src/cpu_map/x86_Snowridge.xml b/src/cpu_map/x86_Snowridge.xml
+new file mode 100644
+index 0000000000..383a24d367
+--- /dev/null
++++ b/src/cpu_map/x86_Snowridge.xml
+@@ -0,0 +1,71 @@
++<cpus>
++  <model name='Snowridge'>
++    <decode host='on' guest='on'/>
++    <signature family='6' model='134'/> <!-- 080665 -->
++    <vendor name='Intel'/>
++    <feature name='3dnowprefetch'/>
++    <feature name='aes'/>
++    <feature name='apic'/>
++    <feature name='arat'/>
++    <feature name='arch-capabilities'/>
++    <feature name='cldemote'/>
++    <feature name='clflush'/>
++    <feature name='clflushopt'/>
++    <feature name='clwb'/>
++    <feature name='cmov'/>
++    <feature name='core-capability'/>
++    <feature name='cx16'/>
++    <feature name='cx8'/>
++    <feature name='de'/>
++    <feature name='erms'/>
++    <feature name='fpu'/>
++    <feature name='fsgsbase'/>
++    <feature name='fxsr'/>
++    <feature name='gfni'/>
++    <feature name='lahf_lm'/>
++    <feature name='lm'/>
++    <feature name='mca'/>
++    <feature name='mce'/>
++    <feature name='mmx'/>
++    <feature name='movbe'/>
++    <feature name='movdir64b'/>
++    <feature name='movdiri'/>
++    <feature name='msr'/>
++    <feature name='mtrr'/>
++    <feature name='nx'/>
++    <feature name='pae'/>
++    <feature name='pat'/>
++    <feature name='pclmuldq'/>
++    <feature name='pdpe1gb'/>
++    <feature name='pge'/>
++    <feature name='pni'/>
++    <feature name='popcnt'/>
++    <feature name='pse'/>
++    <feature name='pse36'/>
++    <feature name='rdrand'/>
++    <feature name='rdseed'/>
++    <feature name='rdtscp'/>
++    <feature name='sep'/>
++    <feature name='sha-ni'/>
++    <feature name='smap'/>
++    <feature name='smep'/>
++    <feature name='spec-ctrl'/>
++    <feature name='split-lock-detect'/>
++    <feature name='ssbd'/>
++    <feature name='sse'/>
++    <feature name='sse2'/>
++    <feature name='sse4.1'/>
++    <feature name='sse4.2'/>
++    <feature name='ssse3'/>
++    <feature name='syscall'/>
++    <feature name='tsc'/>
++    <feature name='tsc-deadline'/>
++    <feature name='umip'/>
++    <feature name='vme'/>
++    <feature name='x2apic'/>
++    <feature name='xgetbv1'/>
++    <feature name='xsave'/>
++    <feature name='xsavec'/>
++    <feature name='xsaveopt'/>
++  </model>
++</cpus>
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml
+index 2eeff136c4..f28e70b9e0 100644
+--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml
+@@ -1,5 +1,5 @@
+ <cpu mode='custom' match='exact'>
+-  <model fallback='forbid'>IvyBridge-IBRS</model>
++  <model fallback='forbid'>Snowridge</model>
+   <vendor>Intel</vendor>
+   <feature policy='require' name='ds'/>
+   <feature policy='require' name='acpi'/>
+@@ -16,36 +16,17 @@
+   <feature policy='require' name='tm2'/>
+   <feature policy='require' name='xtpr'/>
+   <feature policy='require' name='pdcm'/>
+-  <feature policy='require' name='movbe'/>
+   <feature policy='require' name='osxsave'/>
+-  <feature policy='require' name='arat'/>
+   <feature policy='require' name='tsc_adjust'/>
+   <feature policy='require' name='cmt'/>
+-  <feature policy='require' name='rdseed'/>
+-  <feature policy='require' name='smap'/>
+-  <feature policy='require' name='clflushopt'/>
+-  <feature policy='require' name='clwb'/>
+   <feature policy='require' name='intel-pt'/>
+-  <feature policy='require' name='sha-ni'/>
+-  <feature policy='require' name='umip'/>
+   <feature policy='require' name='waitpkg'/>
+-  <feature policy='require' name='gfni'/>
+   <feature policy='require' name='rdpid'/>
+-  <feature policy='require' name='cldemote'/>
+-  <feature policy='require' name='movdiri'/>
+-  <feature policy='require' name='movdir64b'/>
+   <feature policy='require' name='md-clear'/>
+   <feature policy='require' name='stibp'/>
+-  <feature policy='require' name='arch-capabilities'/>
+-  <feature policy='require' name='core-capability'/>
+-  <feature policy='require' name='ssbd'/>
+-  <feature policy='require' name='xsaveopt'/>
+-  <feature policy='require' name='xsavec'/>
+-  <feature policy='require' name='xgetbv1'/>
+   <feature policy='require' name='xsaves'/>
+   <feature policy='require' name='mbm_total'/>
+   <feature policy='require' name='mbm_local'/>
+-  <feature policy='require' name='3dnowprefetch'/>
+   <feature policy='require' name='invtsc'/>
+   <feature policy='require' name='rdctl-no'/>
+   <feature policy='require' name='ibrs-all'/>
+@@ -53,7 +34,8 @@
+   <feature policy='require' name='mds-no'/>
+   <feature policy='require' name='pschange-mc-no'/>
+   <feature policy='require' name='taa-no'/>
+-  <feature policy='require' name='split-lock-detect'/>
+-  <feature policy='disable' name='avx'/>
+-  <feature policy='disable' name='f16c'/>
++  <feature policy='disable' name='mpx'/>
++  <feature policy='disable' name='core-capability'/>
++  <feature policy='disable' name='pdpe1gb'/>
++  <feature policy='disable' name='split-lock-detect'/>
+ </cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml
+index ca685d2f80..bbe0919706 100644
+--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml
+@@ -1,33 +1,15 @@
+ <cpu mode='custom' match='exact'>
+-  <model fallback='forbid'>IvyBridge-IBRS</model>
++  <model fallback='forbid'>Snowridge</model>
+   <vendor>Intel</vendor>
+   <feature policy='require' name='ss'/>
+   <feature policy='require' name='vmx'/>
+   <feature policy='require' name='pdcm'/>
+-  <feature policy='require' name='movbe'/>
+   <feature policy='require' name='hypervisor'/>
+-  <feature policy='require' name='arat'/>
+   <feature policy='require' name='tsc_adjust'/>
+-  <feature policy='require' name='rdseed'/>
+-  <feature policy='require' name='smap'/>
+-  <feature policy='require' name='clflushopt'/>
+-  <feature policy='require' name='clwb'/>
+-  <feature policy='require' name='sha-ni'/>
+-  <feature policy='require' name='umip'/>
+-  <feature policy='require' name='gfni'/>
+   <feature policy='require' name='rdpid'/>
+-  <feature policy='require' name='cldemote'/>
+-  <feature policy='require' name='movdiri'/>
+-  <feature policy='require' name='movdir64b'/>
+   <feature policy='require' name='md-clear'/>
+   <feature policy='require' name='stibp'/>
+-  <feature policy='require' name='arch-capabilities'/>
+-  <feature policy='require' name='ssbd'/>
+-  <feature policy='require' name='xsaveopt'/>
+-  <feature policy='require' name='xsavec'/>
+-  <feature policy='require' name='xgetbv1'/>
+   <feature policy='require' name='xsaves'/>
+-  <feature policy='require' name='3dnowprefetch'/>
+   <feature policy='require' name='ibpb'/>
+   <feature policy='require' name='amd-stibp'/>
+   <feature policy='require' name='amd-ssbd'/>
+@@ -36,6 +18,8 @@
+   <feature policy='require' name='skip-l1dfl-vmentry'/>
+   <feature policy='require' name='mds-no'/>
+   <feature policy='require' name='pschange-mc-no'/>
+-  <feature policy='disable' name='avx'/>
+-  <feature policy='disable' name='f16c'/>
++  <feature policy='disable' name='mpx'/>
++  <feature policy='disable' name='core-capability'/>
++  <feature policy='disable' name='pdpe1gb'/>
++  <feature policy='disable' name='split-lock-detect'/>
+ </cpu>
+diff --git a/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml
+index f4ddb66e38..228acde33b 100644
+--- a/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml
++++ b/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml
+@@ -63,6 +63,7 @@
+       <model usable='no'>athlon</model>
+       <model usable='yes'>Westmere-IBRS</model>
+       <model usable='yes'>Westmere</model>
++      <model usable='no'>Snowridge</model>
+       <model usable='no'>Skylake-Server-IBRS</model>
+       <model usable='no'>Skylake-Server</model>
+       <model usable='yes'>Skylake-Client-IBRS</model>
+diff --git a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml
+index d6265ce243..bda1aba8ed 100644
+--- a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml
++++ b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml
+@@ -75,6 +75,7 @@
+       <model usable='yes'>athlon</model>
+       <model usable='no'>Westmere-IBRS</model>
+       <model usable='no'>Westmere</model>
++      <model usable='no'>Snowridge</model>
+       <model usable='no'>Skylake-Server-IBRS</model>
+       <model usable='no'>Skylake-Server</model>
+       <model usable='no'>Skylake-Client-IBRS</model>
+diff --git a/tests/domaincapsdata/qemu_4.1.0.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0.x86_64.xml
+index bcc8bbcc7a..bb53138712 100644
+--- a/tests/domaincapsdata/qemu_4.1.0.x86_64.xml
++++ b/tests/domaincapsdata/qemu_4.1.0.x86_64.xml
+@@ -62,6 +62,7 @@
+       <model usable='no'>athlon</model>
+       <model usable='yes'>Westmere-IBRS</model>
+       <model usable='yes'>Westmere</model>
++      <model usable='no'>Snowridge</model>
+       <model usable='no'>Skylake-Server-IBRS</model>
+       <model usable='no'>Skylake-Server</model>
+       <model usable='yes'>Skylake-Client-IBRS</model>
+diff --git a/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml
+index 4d9616cb69..0a3f3ef564 100644
+--- a/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml
++++ b/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml
+@@ -64,6 +64,7 @@
+       <model usable='no'>athlon</model>
+       <model usable='yes'>Westmere-IBRS</model>
+       <model usable='yes'>Westmere</model>
++      <model usable='no'>Snowridge</model>
+       <model usable='no'>Skylake-Server-noTSX-IBRS</model>
+       <model usable='no'>Skylake-Server-IBRS</model>
+       <model usable='no'>Skylake-Server</model>
+diff --git a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml
+index bcaf9afd6f..e64b647f51 100644
+--- a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml
++++ b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml
+@@ -75,6 +75,7 @@
+       <model usable='yes'>athlon</model>
+       <model usable='no'>Westmere-IBRS</model>
+       <model usable='no'>Westmere</model>
++      <model usable='no'>Snowridge</model>
+       <model usable='no'>Skylake-Server-noTSX-IBRS</model>
+       <model usable='no'>Skylake-Server-IBRS</model>
+       <model usable='no'>Skylake-Server</model>
+diff --git a/tests/domaincapsdata/qemu_4.2.0.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0.x86_64.xml
+index 5210c917aa..5525758a48 100644
+--- a/tests/domaincapsdata/qemu_4.2.0.x86_64.xml
++++ b/tests/domaincapsdata/qemu_4.2.0.x86_64.xml
+@@ -63,6 +63,7 @@
+       <model usable='no'>athlon</model>
+       <model usable='yes'>Westmere-IBRS</model>
+       <model usable='yes'>Westmere</model>
++      <model usable='no'>Snowridge</model>
+       <model usable='no'>Skylake-Server-noTSX-IBRS</model>
+       <model usable='no'>Skylake-Server-IBRS</model>
+       <model usable='no'>Skylake-Server</model>
+diff --git a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml
+index b2a7087a0e..4cb4bf6cce 100644
+--- a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml
++++ b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml
+@@ -64,6 +64,7 @@
+       <model usable='no'>athlon</model>
+       <model usable='yes'>Westmere-IBRS</model>
+       <model usable='yes'>Westmere</model>
++      <model usable='no'>Snowridge</model>
+       <model usable='no'>Skylake-Server-noTSX-IBRS</model>
+       <model usable='no'>Skylake-Server-IBRS</model>
+       <model usable='no'>Skylake-Server</model>
+diff --git a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml
+index 39b11fb634..b5986404ae 100644
+--- a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml
++++ b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml
+@@ -74,6 +74,7 @@
+       <model usable='yes'>athlon</model>
+       <model usable='no'>Westmere-IBRS</model>
+       <model usable='yes'>Westmere</model>
++      <model usable='no'>Snowridge</model>
+       <model usable='no'>Skylake-Server-noTSX-IBRS</model>
+       <model usable='no'>Skylake-Server-IBRS</model>
+       <model usable='no'>Skylake-Server</model>
+diff --git a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml
+index 3a1ee23302..0297ce600b 100644
+--- a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml
++++ b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml
+@@ -63,6 +63,7 @@
+       <model usable='no'>athlon</model>
+       <model usable='yes'>Westmere-IBRS</model>
+       <model usable='yes'>Westmere</model>
++      <model usable='no'>Snowridge</model>
+       <model usable='no'>Skylake-Server-noTSX-IBRS</model>
+       <model usable='no'>Skylake-Server-IBRS</model>
+       <model usable='no'>Skylake-Server</model>
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-cpu_map-Defined-and-enable-EPYC-Rome-model.patch b/SOURCES/libvirt-cpu_map-Defined-and-enable-EPYC-Rome-model.patch
new file mode 100644
index 0000000..0e6323a
--- /dev/null
+++ b/SOURCES/libvirt-cpu_map-Defined-and-enable-EPYC-Rome-model.patch
@@ -0,0 +1,310 @@
+From f441299f1b589a60199156a217c5f49fc9de954d Mon Sep 17 00:00:00 2001
+Message-Id: <f441299f1b589a60199156a217c5f49fc9de954d@dist-git>
+From: Markus Schade <markus.schade@hetzner.com>
+Date: Thu, 8 Oct 2020 18:01:25 +0200
+Subject: [PATCH] cpu_map: Defined and enable EPYC-Rome model
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Markus Schade <markus.schade@hetzner.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit f941639f86f4bc66c106eb1291f1b58cf9e24680)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1861506
+
+Conflicts:
+	src/cpu_map/meson.build
+            - the corresponding change was applied to Makefile.inc.am as
+              downstream still uses autotools
+
+	tests/cputest.c
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-host.xml
+            - test data for Ryzen 9 3900X are not present downstream
+
+	tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml
+	tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml
+	tests/domaincapsdata/qemu_5.1.0.x86_64.xml
+	tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml
+	tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml
+	tests/domaincapsdata/qemu_5.2.0.x86_64.xml
+            - not present downstream
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Message-Id: <bc87b8a0b0c408f380792eaf63ff07551185d3a5.1602172344.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/cpu_map/Makefile.inc.am                   |  1 +
+ src/cpu_map/index.xml                         |  1 +
+ src/cpu_map/x86_EPYC-Rome.xml                 | 84 +++++++++++++++++++
+ .../x86_64-cpuid-EPYC-7502-32-Core-guest.xml  | 12 +--
+ .../x86_64-cpuid-EPYC-7502-32-Core-host.xml   | 12 +--
+ .../x86_64-cpuid-EPYC-7502-32-Core-json.xml   | 12 +--
+ .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml  |  1 +
+ .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml  |  1 +
+ tests/domaincapsdata/qemu_5.0.0.x86_64.xml    |  1 +
+ 9 files changed, 92 insertions(+), 33 deletions(-)
+ create mode 100644 src/cpu_map/x86_EPYC-Rome.xml
+
+diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am
+index b949cb0bea..aad4b410f9 100644
+--- a/src/cpu_map/Makefile.inc.am
++++ b/src/cpu_map/Makefile.inc.am
+@@ -30,6 +30,7 @@ cpumap_DATA = \
+ 	cpu_map/x86_Dhyana.xml \
+ 	cpu_map/x86_EPYC.xml \
+ 	cpu_map/x86_EPYC-IBPB.xml \
++	cpu_map/x86_EPYC-Rome.xml \
+ 	cpu_map/x86_Haswell.xml \
+ 	cpu_map/x86_Haswell-IBRS.xml \
+ 	cpu_map/x86_Haswell-noTSX.xml \
+diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml
+index ff1da2e677..633b017a93 100644
+--- a/src/cpu_map/index.xml
++++ b/src/cpu_map/index.xml
+@@ -66,6 +66,7 @@
+     <include filename="x86_Opteron_G5.xml"/>
+     <include filename="x86_EPYC.xml"/>
+     <include filename="x86_EPYC-IBPB.xml"/>
++    <include filename="x86_EPYC-Rome.xml"/>
+ 
+     <!-- Hygon CPU models -->
+     <include filename="x86_Dhyana.xml"/>
+diff --git a/src/cpu_map/x86_EPYC-Rome.xml b/src/cpu_map/x86_EPYC-Rome.xml
+new file mode 100644
+index 0000000000..99fc015fdd
+--- /dev/null
++++ b/src/cpu_map/x86_EPYC-Rome.xml
+@@ -0,0 +1,84 @@
++<cpus>
++  <model name='EPYC-Rome'>
++    <decode host='on' guest='on'/>
++    <signature family='23' model='49'/>
++    <vendor name='AMD'/>
++    <feature name='3dnowprefetch'/>
++    <feature name='abm'/>
++    <feature name='adx'/>
++    <feature name='aes'/>
++    <feature name='amd-stibp'/>
++    <feature name='apic'/>
++    <feature name='arat'/>
++    <feature name='avx'/>
++    <feature name='avx2'/>
++    <feature name='bmi1'/>
++    <feature name='bmi2'/>
++    <feature name='clflush'/>
++    <feature name='clflushopt'/>
++    <feature name='clwb'/>
++    <feature name='clzero'/>
++    <feature name='cmov'/>
++    <feature name='cr8legacy'/>
++    <feature name='cx16'/>
++    <feature name='cx8'/>
++    <feature name='de'/>
++    <feature name='f16c'/>
++    <feature name='fma'/>
++    <feature name='fpu'/>
++    <feature name='fsgsbase'/>
++    <feature name='fxsr'/>
++    <feature name='fxsr_opt'/>
++    <feature name='ibpb'/>
++    <feature name='lahf_lm'/>
++    <feature name='lm'/>
++    <feature name='mca'/>
++    <feature name='mce'/>
++    <feature name='misalignsse'/>
++    <feature name='mmx'/>
++    <feature name='mmxext'/>
++    <feature name='monitor'/>
++    <feature name='movbe'/>
++    <feature name='msr'/>
++    <feature name='mtrr'/>
++    <feature name='npt'/>
++    <feature name='nrip-save'/>
++    <feature name='nx'/>
++    <feature name='osvw'/>
++    <feature name='pae'/>
++    <feature name='pat'/>
++    <feature name='pclmuldq'/>
++    <feature name='pdpe1gb'/>
++    <feature name='perfctr_core'/>
++    <feature name='pge'/>
++    <feature name='pni'/>
++    <feature name='popcnt'/>
++    <feature name='pse'/>
++    <feature name='pse36'/>
++    <feature name='rdpid'/>
++    <feature name='rdrand'/>
++    <feature name='rdseed'/>
++    <feature name='rdtscp'/>
++    <feature name='sep'/>
++    <feature name='sha-ni'/>
++    <feature name='smap'/>
++    <feature name='smep'/>
++    <feature name='sse'/>
++    <feature name='sse2'/>
++    <feature name='sse4.1'/>
++    <feature name='sse4.2'/>
++    <feature name='sse4a'/>
++    <feature name='ssse3'/>
++    <feature name='svm'/>
++    <feature name='syscall'/>
++    <feature name='tsc'/>
++    <feature name='umip'/>
++    <feature name='vme'/>
++    <feature name='wbnoinvd'/>
++    <feature name='xgetbv1'/>
++    <feature name='xsave'/>
++    <feature name='xsavec'/>
++    <feature name='xsaveerptr'/>
++    <feature name='xsaveopt'/>
++  </model>
++</cpus>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml
+index 1320f65a58..cb2caab6f5 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml
+@@ -1,12 +1,9 @@
+ <cpu mode='custom' match='exact'>
+-  <model fallback='forbid'>EPYC-IBPB</model>
++  <model fallback='forbid'>EPYC-Rome</model>
+   <vendor>AMD</vendor>
+   <feature policy='require' name='ht'/>
+   <feature policy='require' name='osxsave'/>
+   <feature policy='require' name='cmt'/>
+-  <feature policy='require' name='clwb'/>
+-  <feature policy='require' name='umip'/>
+-  <feature policy='require' name='rdpid'/>
+   <feature policy='require' name='xsaves'/>
+   <feature policy='require' name='mbm_total'/>
+   <feature policy='require' name='mbm_local'/>
+@@ -17,18 +14,11 @@
+   <feature policy='require' name='wdt'/>
+   <feature policy='require' name='tce'/>
+   <feature policy='require' name='topoext'/>
+-  <feature policy='require' name='perfctr_core'/>
+   <feature policy='require' name='perfctr_nb'/>
+   <feature policy='require' name='invtsc'/>
+-  <feature policy='require' name='clzero'/>
+-  <feature policy='require' name='xsaveerptr'/>
+-  <feature policy='require' name='wbnoinvd'/>
+-  <feature policy='require' name='amd-stibp'/>
+   <feature policy='require' name='amd-ssbd'/>
+-  <feature policy='require' name='npt'/>
+   <feature policy='require' name='lbrv'/>
+   <feature policy='require' name='svm-lock'/>
+-  <feature policy='require' name='nrip-save'/>
+   <feature policy='require' name='tsc-scale'/>
+   <feature policy='require' name='vmcb-clean'/>
+   <feature policy='require' name='flushbyasid'/>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml
+index 37905ec812..b6784f9eba 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml
+@@ -1,13 +1,10 @@
+ <cpu>
+   <arch>x86_64</arch>
+-  <model>EPYC-IBPB</model>
++  <model>EPYC-Rome</model>
+   <vendor>AMD</vendor>
+   <feature name='ht'/>
+   <feature name='osxsave'/>
+   <feature name='cmt'/>
+-  <feature name='clwb'/>
+-  <feature name='umip'/>
+-  <feature name='rdpid'/>
+   <feature name='xsaves'/>
+   <feature name='mbm_total'/>
+   <feature name='mbm_local'/>
+@@ -18,18 +15,11 @@
+   <feature name='wdt'/>
+   <feature name='tce'/>
+   <feature name='topoext'/>
+-  <feature name='perfctr_core'/>
+   <feature name='perfctr_nb'/>
+   <feature name='invtsc'/>
+-  <feature name='clzero'/>
+-  <feature name='xsaveerptr'/>
+-  <feature name='wbnoinvd'/>
+-  <feature name='amd-stibp'/>
+   <feature name='amd-ssbd'/>
+-  <feature name='npt'/>
+   <feature name='lbrv'/>
+   <feature name='svm-lock'/>
+-  <feature name='nrip-save'/>
+   <feature name='tsc-scale'/>
+   <feature name='vmcb-clean'/>
+   <feature name='flushbyasid'/>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml
+index 225cf63852..86466c0547 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml
+@@ -1,28 +1,18 @@
+ <cpu mode='custom' match='exact'>
+-  <model fallback='forbid'>EPYC-IBPB</model>
++  <model fallback='forbid'>EPYC-Rome</model>
+   <vendor>AMD</vendor>
+   <feature policy='require' name='x2apic'/>
+   <feature policy='require' name='tsc-deadline'/>
+   <feature policy='require' name='hypervisor'/>
+   <feature policy='require' name='tsc_adjust'/>
+-  <feature policy='require' name='clwb'/>
+-  <feature policy='require' name='umip'/>
+-  <feature policy='require' name='rdpid'/>
+   <feature policy='require' name='spec-ctrl'/>
+   <feature policy='require' name='stibp'/>
+   <feature policy='require' name='arch-capabilities'/>
+   <feature policy='require' name='ssbd'/>
+   <feature policy='require' name='xsaves'/>
+   <feature policy='require' name='cmp_legacy'/>
+-  <feature policy='require' name='perfctr_core'/>
+-  <feature policy='require' name='clzero'/>
+-  <feature policy='require' name='xsaveerptr'/>
+-  <feature policy='require' name='wbnoinvd'/>
+-  <feature policy='require' name='amd-stibp'/>
+   <feature policy='require' name='amd-ssbd'/>
+   <feature policy='require' name='virt-ssbd'/>
+-  <feature policy='require' name='npt'/>
+-  <feature policy='require' name='nrip-save'/>
+   <feature policy='require' name='rdctl-no'/>
+   <feature policy='require' name='skip-l1dfl-vmentry'/>
+   <feature policy='require' name='mds-no'/>
+diff --git a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml
+index 7bfd786ff6..b2a7087a0e 100644
+--- a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml
++++ b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml
+@@ -90,6 +90,7 @@
+       <model usable='yes'>Haswell-noTSX</model>
+       <model usable='yes'>Haswell-IBRS</model>
+       <model usable='yes'>Haswell</model>
++      <model usable='no'>EPYC-Rome</model>
+       <model usable='no'>EPYC-IBPB</model>
+       <model usable='no'>EPYC</model>
+       <model usable='no'>Dhyana</model>
+diff --git a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml
+index eb456dea28..39b11fb634 100644
+--- a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml
++++ b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml
+@@ -100,6 +100,7 @@
+       <model usable='no'>Haswell-noTSX</model>
+       <model usable='no'>Haswell-IBRS</model>
+       <model usable='no'>Haswell</model>
++      <model usable='no'>EPYC-Rome</model>
+       <model usable='no'>EPYC-IBPB</model>
+       <model usable='no'>EPYC</model>
+       <model usable='no'>Dhyana</model>
+diff --git a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml
+index d6ee66ab60..3a1ee23302 100644
+--- a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml
++++ b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml
+@@ -89,6 +89,7 @@
+       <model usable='yes'>Haswell-noTSX</model>
+       <model usable='yes'>Haswell-IBRS</model>
+       <model usable='yes'>Haswell</model>
++      <model usable='no'>EPYC-Rome</model>
+       <model usable='no'>EPYC-IBPB</model>
+       <model usable='no'>EPYC</model>
+       <model usable='no'>Dhyana</model>
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-cpu_map-Fix-Icelake-Server-model-number.patch b/SOURCES/libvirt-cpu_map-Fix-Icelake-Server-model-number.patch
new file mode 100644
index 0000000..0ec9af6
--- /dev/null
+++ b/SOURCES/libvirt-cpu_map-Fix-Icelake-Server-model-number.patch
@@ -0,0 +1,52 @@
+From a6293a2b28a65f3c9ae0dcf387b222ebd242fa63 Mon Sep 17 00:00:00 2001
+Message-Id: <a6293a2b28a65f3c9ae0dcf387b222ebd242fa63@dist-git>
+From: Tim Wiederhake <twiederh@redhat.com>
+Date: Fri, 15 Jan 2021 15:17:17 +0100
+Subject: [PATCH] cpu_map: Fix Icelake Server model number
+
+See arch/x86/include/asm/intel-family.h in the Kernel:
+  #define INTEL_FAM6_ICELAKE_X		0x6A
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit 1278ac6265589cd83cc2e661056c860e98105507)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1537734
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Message-Id: <20210115141722.14986-2-twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/cpu_map/x86_Icelake-Server-noTSX.xml | 2 +-
+ src/cpu_map/x86_Icelake-Server.xml       | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/cpu_map/x86_Icelake-Server-noTSX.xml b/src/cpu_map/x86_Icelake-Server-noTSX.xml
+index 2fd6906406..34a0f7c18c 100644
+--- a/src/cpu_map/x86_Icelake-Server-noTSX.xml
++++ b/src/cpu_map/x86_Icelake-Server-noTSX.xml
+@@ -1,7 +1,7 @@
+ <cpus>
+   <model name='Icelake-Server-noTSX'>
+     <decode host='on' guest='off'/>
+-    <signature family='6' model='134'/> <!-- 080660 -->
++    <signature family='6' model='106'/> <!-- 0606A5 -->
+     <vendor name='Intel'/>
+     <feature name='3dnowprefetch'/>
+     <feature name='abm'/>
+diff --git a/src/cpu_map/x86_Icelake-Server.xml b/src/cpu_map/x86_Icelake-Server.xml
+index 367ade7240..1ee4ea9cd4 100644
+--- a/src/cpu_map/x86_Icelake-Server.xml
++++ b/src/cpu_map/x86_Icelake-Server.xml
+@@ -1,7 +1,7 @@
+ <cpus>
+   <model name='Icelake-Server'>
+     <decode host='on' guest='on'/>
+-    <signature family='6' model='134'/> <!-- 080660 -->
++    <signature family='6' model='106'/> <!-- 0606A5 -->
+     <vendor name='Intel'/>
+     <feature name='3dnowprefetch'/>
+     <feature name='abm'/>
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-cpu_map-Fix-spelling-of-svme-addr-chk-feature.patch b/SOURCES/libvirt-cpu_map-Fix-spelling-of-svme-addr-chk-feature.patch
new file mode 100644
index 0000000..a603df9
--- /dev/null
+++ b/SOURCES/libvirt-cpu_map-Fix-spelling-of-svme-addr-chk-feature.patch
@@ -0,0 +1,59 @@
+From a7fb45c4e5a807a7b437a91cfc96c8c811351578 Mon Sep 17 00:00:00 2001
+Message-Id: <a7fb45c4e5a807a7b437a91cfc96c8c811351578@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Thu, 4 Mar 2021 09:41:53 +0100
+Subject: [PATCH] cpu_map: Fix spelling of svme-addr-chk feature
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit a208176ca1d9eedf8aa6bf12fde6a7a9579ab549 introduced this feature
+with an incorrect "svme-addr-check" spelling.
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Tim Wiederhake <twiederh@redhat.com>
+(cherry picked from commit b5abf9a192248b1005f63a7102d2627375d70fe5)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1926864
+
+Conflicts:
+	src/cpu_map/sync_qemu_i386.py
+            - the original change to this file was not backported
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Message-Id: <75071287f9fc55f4bec82916726fcb8f31c1e014.1614847231.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/cpu_map/x86_EPYC-Milan.xml | 2 +-
+ src/cpu_map/x86_features.xml   | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/cpu_map/x86_EPYC-Milan.xml b/src/cpu_map/x86_EPYC-Milan.xml
+index 53f0cd6aac..3055e175fa 100644
+--- a/src/cpu_map/x86_EPYC-Milan.xml
++++ b/src/cpu_map/x86_EPYC-Milan.xml
+@@ -76,7 +76,7 @@
+     <feature name='sse4a'/>
+     <feature name='ssse3'/>
+     <feature name='svm'/>
+-    <feature name='svme-addr-check'/>
++    <feature name='svme-addr-chk'/>
+     <feature name='syscall'/>
+     <feature name='tsc'/>
+     <feature name='umip'/>
+diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml
+index 8acd42f796..ba23f553c3 100644
+--- a/src/cpu_map/x86_features.xml
++++ b/src/cpu_map/x86_features.xml
+@@ -548,7 +548,7 @@
+   <feature name='pfthreshold'>
+     <cpuid eax_in='0x8000000a' edx='0x00001000'/>
+   </feature>
+-  <feature name='svme-addr-check'>
++  <feature name='svme-addr-chk'>
+     <cpuid eax_in='0x8000000a' edx='0x10000000'/>
+   </feature>
+ 
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-cpu_map-Install-x86_EPYC-Milan.xml.patch b/SOURCES/libvirt-cpu_map-Install-x86_EPYC-Milan.xml.patch
new file mode 100644
index 0000000..4652d0e
--- /dev/null
+++ b/SOURCES/libvirt-cpu_map-Install-x86_EPYC-Milan.xml.patch
@@ -0,0 +1,41 @@
+From 8b1e1aa7cb9dc428a36b549a73286ec7040864ed Mon Sep 17 00:00:00 2001
+Message-Id: <8b1e1aa7cb9dc428a36b549a73286ec7040864ed@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Wed, 3 Mar 2021 11:11:55 +0100
+Subject: [PATCH] cpu_map: Install x86_EPYC-Milan.xml
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+(cherry picked from commit d3de79dbfc20dc4dfc19154b16079861c542b71e)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1926864
+
+Conflicts:
+	src/cpu_map/meson.build
+            - change goes to Makefile.inc.am instead
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Message-Id: <77cf69a7222fd9fc5ef0f1c25f0534090c29865f.1614766279.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/cpu_map/Makefile.inc.am | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am
+index 1dd78c6715..45dbe9e216 100644
+--- a/src/cpu_map/Makefile.inc.am
++++ b/src/cpu_map/Makefile.inc.am
+@@ -30,6 +30,7 @@ cpumap_DATA = \
+ 	cpu_map/x86_Dhyana.xml \
+ 	cpu_map/x86_EPYC.xml \
+ 	cpu_map/x86_EPYC-IBPB.xml \
++	cpu_map/x86_EPYC-Milan.xml \
+ 	cpu_map/x86_EPYC-Rome.xml \
+ 	cpu_map/x86_Haswell.xml \
+ 	cpu_map/x86_Haswell-IBRS.xml \
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-cpu_map-Remove-monitor-feature-from-EPYC-Rome.patch b/SOURCES/libvirt-cpu_map-Remove-monitor-feature-from-EPYC-Rome.patch
new file mode 100644
index 0000000..09af67b
--- /dev/null
+++ b/SOURCES/libvirt-cpu_map-Remove-monitor-feature-from-EPYC-Rome.patch
@@ -0,0 +1,90 @@
+From b91bb231645300a29ab82994a003ba22835ee994 Mon Sep 17 00:00:00 2001
+Message-Id: <b91bb231645300a29ab82994a003ba22835ee994@dist-git>
+From: Jiri Denemark <jdenemar@redhat.com>
+Date: Thu, 8 Oct 2020 18:01:26 +0200
+Subject: [PATCH] cpu_map: Remove monitor feature from EPYC-Rome
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The feature is filtered by KVM and never automatically enabled. So even
+though QEMU definition of EPYC-Rome contains this feature, the guest
+won't see it. Also domain capabilities will show it as disabled for KVM
+domains. Thus the feature should not really be included in our
+definition of EPYC-Rome.
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+(cherry picked from commit 3bf6f9fe22dfbd3c1dcc614b31f2f4fe8b71a2f2)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1861506
+
+Conflicts:
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-guest.xml
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-host.xml
+	tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-json.xml
+	tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml
+	tests/domaincapsdata/qemu_5.1.0.x86_64.xml
+	tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml
+	tests/domaincapsdata/qemu_5.2.0.x86_64.xml
+            - not present downstream
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Message-Id: <74b9257f49925312b025a99dd934a9613ca295d4.1602172344.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/cpu_map/x86_EPYC-Rome.xml                              | 1 -
+ tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml | 1 +
+ tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml  | 1 +
+ tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml  | 1 -
+ 4 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/cpu_map/x86_EPYC-Rome.xml b/src/cpu_map/x86_EPYC-Rome.xml
+index 99fc015fdd..e54d0a48d8 100644
+--- a/src/cpu_map/x86_EPYC-Rome.xml
++++ b/src/cpu_map/x86_EPYC-Rome.xml
+@@ -37,7 +37,6 @@
+     <feature name='misalignsse'/>
+     <feature name='mmx'/>
+     <feature name='mmxext'/>
+-    <feature name='monitor'/>
+     <feature name='movbe'/>
+     <feature name='msr'/>
+     <feature name='mtrr'/>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml
+index cb2caab6f5..6d95b508b2 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml
+@@ -2,6 +2,7 @@
+   <model fallback='forbid'>EPYC-Rome</model>
+   <vendor>AMD</vendor>
+   <feature policy='require' name='ht'/>
++  <feature policy='require' name='monitor'/>
+   <feature policy='require' name='osxsave'/>
+   <feature policy='require' name='cmt'/>
+   <feature policy='require' name='xsaves'/>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml
+index b6784f9eba..65eaeabdd0 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml
+@@ -3,6 +3,7 @@
+   <model>EPYC-Rome</model>
+   <vendor>AMD</vendor>
+   <feature name='ht'/>
++  <feature name='monitor'/>
+   <feature name='osxsave'/>
+   <feature name='cmt'/>
+   <feature name='xsaves'/>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml
+index 86466c0547..febfdfcf2b 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml
+@@ -17,5 +17,4 @@
+   <feature policy='require' name='skip-l1dfl-vmentry'/>
+   <feature policy='require' name='mds-no'/>
+   <feature policy='require' name='pschange-mc-no'/>
+-  <feature policy='disable' name='monitor'/>
+ </cpu>
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-cpumap-Add-support-for-ibrs-CPU-feature.patch b/SOURCES/libvirt-cpumap-Add-support-for-ibrs-CPU-feature.patch
new file mode 100644
index 0000000..9fcd3a4
--- /dev/null
+++ b/SOURCES/libvirt-cpumap-Add-support-for-ibrs-CPU-feature.patch
@@ -0,0 +1,65 @@
+From bb9f39342d4ea6b76b67378f514f52a9627206b9 Mon Sep 17 00:00:00 2001
+Message-Id: <bb9f39342d4ea6b76b67378f514f52a9627206b9@dist-git>
+From: Tim Wiederhake <twiederh@redhat.com>
+Date: Wed, 3 Mar 2021 11:11:52 +0100
+Subject: [PATCH] cpumap: Add support for ibrs CPU feature
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit 5c17a7ba41670f3182186c06e621995b5d03fc95)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1926864
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Message-Id: <0aee3baa35e04f56e3c95bb2f60c8a17d7806e7a.1614766279.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/cpu_map/x86_features.xml                               | 3 +++
+ tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml | 1 +
+ tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml  | 1 +
+ 3 files changed, 5 insertions(+)
+
+diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml
+index 83d8e641a8..abefb7928e 100644
+--- a/src/cpu_map/x86_features.xml
++++ b/src/cpu_map/x86_features.xml
+@@ -501,6 +501,9 @@
+   <feature name='ibpb'>
+     <cpuid eax_in='0x80000008' ebx='0x00001000'/>
+   </feature>
++  <feature name='ibrs'>
++    <cpuid eax_in='0x80000008' ebx='0x00004000'/>
++  </feature>
+   <feature name='amd-stibp'>
+     <cpuid eax_in='0x80000008' ebx='0x00008000'/>
+   </feature>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml
+index 6d95b508b2..40e7912398 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml
+@@ -17,6 +17,7 @@
+   <feature policy='require' name='topoext'/>
+   <feature policy='require' name='perfctr_nb'/>
+   <feature policy='require' name='invtsc'/>
++  <feature policy='require' name='ibrs'/>
+   <feature policy='require' name='amd-ssbd'/>
+   <feature policy='require' name='lbrv'/>
+   <feature policy='require' name='svm-lock'/>
+diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml
+index 65eaeabdd0..9f8108cdaa 100644
+--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml
++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml
+@@ -18,6 +18,7 @@
+   <feature name='topoext'/>
+   <feature name='perfctr_nb'/>
+   <feature name='invtsc'/>
++  <feature name='ibrs'/>
+   <feature name='amd-ssbd'/>
+   <feature name='lbrv'/>
+   <feature name='svm-lock'/>
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-cpumap-Add-support-for-svme-addr-check-CPU-feature.patch b/SOURCES/libvirt-cpumap-Add-support-for-svme-addr-check-CPU-feature.patch
new file mode 100644
index 0000000..97d1b6f
--- /dev/null
+++ b/SOURCES/libvirt-cpumap-Add-support-for-svme-addr-check-CPU-feature.patch
@@ -0,0 +1,39 @@
+From 87fdbd2d0ab24f00c70a298317d50df44a5f76ad Mon Sep 17 00:00:00 2001
+Message-Id: <87fdbd2d0ab24f00c70a298317d50df44a5f76ad@dist-git>
+From: Tim Wiederhake <twiederh@redhat.com>
+Date: Wed, 3 Mar 2021 11:11:53 +0100
+Subject: [PATCH] cpumap: Add support for svme-addr-check CPU feature
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit 5ac6ab2fde63881d3c5cc7372a0d0e59618feb55)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1926864
+
+Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
+Message-Id: <aa154754f76021b9f61788944f6c329c6088cf77.1614766279.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/cpu_map/x86_features.xml | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml
+index abefb7928e..8acd42f796 100644
+--- a/src/cpu_map/x86_features.xml
++++ b/src/cpu_map/x86_features.xml
+@@ -548,6 +548,9 @@
+   <feature name='pfthreshold'>
+     <cpuid eax_in='0x8000000a' edx='0x00001000'/>
+   </feature>
++  <feature name='svme-addr-check'>
++    <cpuid eax_in='0x8000000a' edx='0x10000000'/>
++  </feature>
+ 
+   <!-- IA32_ARCH_CAPABILITIES features -->
+   <feature name='rdctl-no'>
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-cputestdata-Add-test-data-for-Snowridge.patch b/SOURCES/libvirt-cputestdata-Add-test-data-for-Snowridge.patch
new file mode 100644
index 0000000..0ee3ed2
--- /dev/null
+++ b/SOURCES/libvirt-cputestdata-Add-test-data-for-Snowridge.patch
@@ -0,0 +1,2763 @@
+From 2d95faf1042465489753179ca46b7ade6225b171 Mon Sep 17 00:00:00 2001
+Message-Id: <2d95faf1042465489753179ca46b7ade6225b171@dist-git>
+From: Tim Wiederhake <twiederh@redhat.com>
+Date: Fri, 15 Jan 2021 15:17:18 +0100
+Subject: [PATCH] cputestdata: Add test data for Snowridge
+
+It's obvious the CPU model detection provides strange results, which
+will be fixed by adding a new Snowridge CPU model few patches later.
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit 59a585fdb047669ee36251c7338bb2e2ccd58998)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1537734
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Message-Id: <20210115141722.14986-3-twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ tests/cputest.c                               |    1 +
+ .../x86_64-cpuid-Atom-P5362-disabled.xml      |    8 +
+ .../x86_64-cpuid-Atom-P5362-enabled.xml       |   10 +
+ .../x86_64-cpuid-Atom-P5362-guest.xml         |   57 +
+ .../x86_64-cpuid-Atom-P5362-host.xml          |   66 +
+ .../x86_64-cpuid-Atom-P5362-json.xml          |   41 +
+ .../cputestdata/x86_64-cpuid-Atom-P5362.json  | 2415 +++++++++++++++++
+ tests/cputestdata/x86_64-cpuid-Atom-P5362.sig |    4 +
+ tests/cputestdata/x86_64-cpuid-Atom-P5362.xml |   61 +
+ 9 files changed, 2663 insertions(+)
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362-enabled.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362.json
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362.sig
+ create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362.xml
+
+diff --git a/tests/cputest.c b/tests/cputest.c
+index 388174eba7..2ec3337476 100644
+--- a/tests/cputest.c
++++ b/tests/cputest.c
+@@ -1218,6 +1218,7 @@ mymain(void)
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "A10-5800K", JSON_HOST);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "Atom-D510", JSON_NONE);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "Atom-N450", JSON_NONE);
++    DO_TEST_CPUID(VIR_ARCH_X86_64, "Atom-P5362", JSON_MODELS_REQUIRED);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i5-650", JSON_MODELS_REQUIRED);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i5-2500", JSON_HOST);
+     DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i5-2540M", JSON_MODELS);
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml
+new file mode 100644
+index 0000000000..842c7b4a2a
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml
+@@ -0,0 +1,8 @@
++<!-- Features disabled by QEMU -->
++<cpudata arch='x86'>
++  <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x080041dc' edx='0xb0600000'/>
++  <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00000020' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/>
++  <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
++  <msr index='0x10a' edx='0x00000000' eax='0x00000100'/>
++</cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-enabled.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-enabled.xml
+new file mode 100644
+index 0000000000..2214d448ef
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-enabled.xml
+@@ -0,0 +1,10 @@
++<!-- Features enabled by QEMU -->
++<cpudata arch='x86'>
++  <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0xc7f8a223' edx='0x0f8bfbff'/>
++  <cpuid eax_in='0x00000006' ecx_in='0x00' eax='0x00000004' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x21940283' ecx='0x1a400104' edx='0xac000400'/>
++  <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x0000000f' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000101' edx='0x28100800'/>
++  <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x01009000' ecx='0x00000000' edx='0x00000000'/>
++  <msr index='0x10a' edx='0x00000000' eax='0x0000006b'/>
++</cpudata>
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml
+new file mode 100644
+index 0000000000..0f3e2e506e
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml
+@@ -0,0 +1,57 @@
++<cpu mode='custom' match='exact'>
++  <model fallback='forbid'>IvyBridge-IBRS</model>
++  <vendor>Intel</vendor>
++  <feature policy='require' name='ds'/>
++  <feature policy='require' name='acpi'/>
++  <feature policy='require' name='ss'/>
++  <feature policy='require' name='ht'/>
++  <feature policy='require' name='tm'/>
++  <feature policy='require' name='pbe'/>
++  <feature policy='require' name='dtes64'/>
++  <feature policy='require' name='monitor'/>
++  <feature policy='require' name='ds_cpl'/>
++  <feature policy='require' name='vmx'/>
++  <feature policy='require' name='smx'/>
++  <feature policy='require' name='est'/>
++  <feature policy='require' name='tm2'/>
++  <feature policy='require' name='xtpr'/>
++  <feature policy='require' name='pdcm'/>
++  <feature policy='require' name='movbe'/>
++  <feature policy='require' name='osxsave'/>
++  <feature policy='require' name='arat'/>
++  <feature policy='require' name='tsc_adjust'/>
++  <feature policy='require' name='cmt'/>
++  <feature policy='require' name='rdseed'/>
++  <feature policy='require' name='smap'/>
++  <feature policy='require' name='clflushopt'/>
++  <feature policy='require' name='clwb'/>
++  <feature policy='require' name='intel-pt'/>
++  <feature policy='require' name='sha-ni'/>
++  <feature policy='require' name='umip'/>
++  <feature policy='require' name='waitpkg'/>
++  <feature policy='require' name='gfni'/>
++  <feature policy='require' name='rdpid'/>
++  <feature policy='require' name='cldemote'/>
++  <feature policy='require' name='movdiri'/>
++  <feature policy='require' name='movdir64b'/>
++  <feature policy='require' name='md-clear'/>
++  <feature policy='require' name='stibp'/>
++  <feature policy='require' name='arch-capabilities'/>
++  <feature policy='require' name='ssbd'/>
++  <feature policy='require' name='xsaveopt'/>
++  <feature policy='require' name='xsavec'/>
++  <feature policy='require' name='xgetbv1'/>
++  <feature policy='require' name='xsaves'/>
++  <feature policy='require' name='mbm_total'/>
++  <feature policy='require' name='mbm_local'/>
++  <feature policy='require' name='3dnowprefetch'/>
++  <feature policy='require' name='invtsc'/>
++  <feature policy='require' name='rdctl-no'/>
++  <feature policy='require' name='ibrs-all'/>
++  <feature policy='require' name='skip-l1dfl-vmentry'/>
++  <feature policy='require' name='mds-no'/>
++  <feature policy='require' name='pschange-mc-no'/>
++  <feature policy='require' name='taa-no'/>
++  <feature policy='disable' name='avx'/>
++  <feature policy='disable' name='f16c'/>
++</cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml
+new file mode 100644
+index 0000000000..3bd009c1da
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml
+@@ -0,0 +1,66 @@
++<cpu>
++  <arch>x86_64</arch>
++  <model>Westmere-IBRS</model>
++  <vendor>Intel</vendor>
++  <feature name='vme'/>
++  <feature name='ds'/>
++  <feature name='acpi'/>
++  <feature name='ss'/>
++  <feature name='ht'/>
++  <feature name='tm'/>
++  <feature name='pbe'/>
++  <feature name='pclmuldq'/>
++  <feature name='dtes64'/>
++  <feature name='monitor'/>
++  <feature name='ds_cpl'/>
++  <feature name='vmx'/>
++  <feature name='smx'/>
++  <feature name='est'/>
++  <feature name='tm2'/>
++  <feature name='xtpr'/>
++  <feature name='pdcm'/>
++  <feature name='x2apic'/>
++  <feature name='movbe'/>
++  <feature name='tsc-deadline'/>
++  <feature name='xsave'/>
++  <feature name='osxsave'/>
++  <feature name='rdrand'/>
++  <feature name='arat'/>
++  <feature name='fsgsbase'/>
++  <feature name='tsc_adjust'/>
++  <feature name='smep'/>
++  <feature name='erms'/>
++  <feature name='cmt'/>
++  <feature name='rdseed'/>
++  <feature name='smap'/>
++  <feature name='clflushopt'/>
++  <feature name='clwb'/>
++  <feature name='intel-pt'/>
++  <feature name='sha-ni'/>
++  <feature name='umip'/>
++  <feature name='waitpkg'/>
++  <feature name='gfni'/>
++  <feature name='rdpid'/>
++  <feature name='cldemote'/>
++  <feature name='movdiri'/>
++  <feature name='movdir64b'/>
++  <feature name='md-clear'/>
++  <feature name='stibp'/>
++  <feature name='arch-capabilities'/>
++  <feature name='ssbd'/>
++  <feature name='xsaveopt'/>
++  <feature name='xsavec'/>
++  <feature name='xgetbv1'/>
++  <feature name='xsaves'/>
++  <feature name='mbm_total'/>
++  <feature name='mbm_local'/>
++  <feature name='rdtscp'/>
++  <feature name='3dnowprefetch'/>
++  <feature name='invtsc'/>
++  <feature name='rdctl-no'/>
++  <feature name='ibrs-all'/>
++  <feature name='skip-l1dfl-vmentry'/>
++  <feature name='mds-no'/>
++  <feature name='pschange-mc-no'/>
++  <feature name='taa-no'/>
++</cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml
+new file mode 100644
+index 0000000000..ca685d2f80
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml
+@@ -0,0 +1,41 @@
++<cpu mode='custom' match='exact'>
++  <model fallback='forbid'>IvyBridge-IBRS</model>
++  <vendor>Intel</vendor>
++  <feature policy='require' name='ss'/>
++  <feature policy='require' name='vmx'/>
++  <feature policy='require' name='pdcm'/>
++  <feature policy='require' name='movbe'/>
++  <feature policy='require' name='hypervisor'/>
++  <feature policy='require' name='arat'/>
++  <feature policy='require' name='tsc_adjust'/>
++  <feature policy='require' name='rdseed'/>
++  <feature policy='require' name='smap'/>
++  <feature policy='require' name='clflushopt'/>
++  <feature policy='require' name='clwb'/>
++  <feature policy='require' name='sha-ni'/>
++  <feature policy='require' name='umip'/>
++  <feature policy='require' name='gfni'/>
++  <feature policy='require' name='rdpid'/>
++  <feature policy='require' name='cldemote'/>
++  <feature policy='require' name='movdiri'/>
++  <feature policy='require' name='movdir64b'/>
++  <feature policy='require' name='md-clear'/>
++  <feature policy='require' name='stibp'/>
++  <feature policy='require' name='arch-capabilities'/>
++  <feature policy='require' name='ssbd'/>
++  <feature policy='require' name='xsaveopt'/>
++  <feature policy='require' name='xsavec'/>
++  <feature policy='require' name='xgetbv1'/>
++  <feature policy='require' name='xsaves'/>
++  <feature policy='require' name='3dnowprefetch'/>
++  <feature policy='require' name='ibpb'/>
++  <feature policy='require' name='amd-stibp'/>
++  <feature policy='require' name='amd-ssbd'/>
++  <feature policy='require' name='rdctl-no'/>
++  <feature policy='require' name='ibrs-all'/>
++  <feature policy='require' name='skip-l1dfl-vmentry'/>
++  <feature policy='require' name='mds-no'/>
++  <feature policy='require' name='pschange-mc-no'/>
++  <feature policy='disable' name='avx'/>
++  <feature policy='disable' name='f16c'/>
++</cpu>
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362.json b/tests/cputestdata/x86_64-cpuid-Atom-P5362.json
+new file mode 100644
+index 0000000000..4e5545f177
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362.json
+@@ -0,0 +1,2415 @@
++{
++  "return": {
++    "model": {
++      "name": "base",
++      "props": {
++        "vmx-entry-load-rtit-ctl": false,
++        "phys-bits": 0,
++        "core-id": -1,
++        "xlevel": 2147483656,
++        "cmov": true,
++        "ia64": false,
++        "ssb-no": false,
++        "aes": true,
++        "vmx-apicv-xapic": true,
++        "mmx": true,
++        "rdpid": true,
++        "vmx-page-walk-4": true,
++        "vmx-page-walk-5": false,
++        "arat": true,
++        "gfni": true,
++        "vmx-desc-exit": true,
++        "ibrs-all": true,
++        "pause-filter": false,
++        "xsavec": true,
++        "intel-pt": false,
++        "vmx-cr8-store-exit": true,
++        "hv-frequencies": false,
++        "tsc-frequency": 0,
++        "vmx-rdseed-exit": true,
++        "xd": true,
++        "x-intel-pt-auto-level": false,
++        "hv-vendor-id": "",
++        "vmx-eptp-switching": true,
++        "kvm-asyncpf": true,
++        "kvm_asyncpf": true,
++        "perfctr_core": false,
++        "perfctr-core": false,
++        "mpx": false,
++        "pbe": false,
++        "decodeassists": false,
++        "avx512cd": false,
++        "vmx-exit-load-efer": true,
++        "vmx-exit-clear-bndcfgs": false,
++        "sse4_1": true,
++        "sse4.1": true,
++        "sse4-1": true,
++        "family": 6,
++        "legacy-cache": true,
++        "vmx-vmwrite-vmexit-fields": true,
++        "vmx-vnmi": true,
++        "vmx-true-ctls": true,
++        "host-phys-bits-limit": 48,
++        "vmx-ept-execonly": true,
++        "vmx-exit-save-efer": true,
++        "vmx-invept-all-context": true,
++        "vmware-cpuid-freq": true,
++        "wbnoinvd": false,
++        "avx512f": false,
++        "hv-stimer-direct": false,
++        "msr": true,
++        "mce": true,
++        "mca": true,
++        "hv-runtime": false,
++        "xcrypt": false,
++        "thread-id": -1,
++        "vmx-exit-load-pat": true,
++        "vmx-intr-exit": true,
++        "min-level": 27,
++        "vmx-flexpriority": true,
++        "xgetbv1": true,
++        "cid": false,
++        "hv-relaxed": false,
++        "hv-crash": false,
++        "ds": false,
++        "fxsr": true,
++        "avx512-bf16": false,
++        "vmx-cr8-load-exit": true,
++        "xsaveopt": true,
++        "vmx-apicv-vid": true,
++        "vmx-exit-save-pat": true,
++        "xtpr": false,
++        "tsx-ctrl": false,
++        "vmx-ple": false,
++        "hv-evmcs": false,
++        "avx512vl": false,
++        "avx512-vpopcntdq": false,
++        "phe": false,
++        "extapic": false,
++        "3dnowprefetch": true,
++        "vmx-vmfunc": true,
++        "vmx-activity-shutdown": false,
++        "avx512vbmi2": false,
++        "vmx-encls-exit": false,
++        "cr8legacy": false,
++        "vmx-msr-bitmap": true,
++        "stibp": true,
++        "cpuid-0xb": true,
++        "xcrypt-en": false,
++        "vmx-mwait-exit": true,
++        "kvm_pv_eoi": true,
++        "vmx-pml": true,
++        "apic-id": 4294967295,
++        "vmx-nmi-exit": true,
++        "vmx-invept-single-context-noglobals": true,
++        "rsba": false,
++        "pn": false,
++        "dca": false,
++        "vendor": "GenuineIntel",
++        "vmx-unrestricted-guest": true,
++        "hv-ipi": false,
++        "vmx-cr3-store-noexit": true,
++        "pku": false,
++        "smx": false,
++        "cmp_legacy": false,
++        "cmp-legacy": false,
++        "node-id": -1,
++        "avx512-4fmaps": false,
++        "vmcb_clean": false,
++        "vmcb-clean": false,
++        "3dnowext": false,
++        "amd-no-ssb": false,
++        "hle": false,
++        "npt": false,
++        "rdctl-no": true,
++        "vmx-invvpid": true,
++        "memory": "/machine/unattached/system[0]",
++        "clwb": true,
++        "lbrv": false,
++        "adx": false,
++        "ss": true,
++        "pni": true,
++        "svm_lock": false,
++        "svm-lock": false,
++        "pfthreshold": false,
++        "smep": true,
++        "smap": true,
++        "vmx-invpcid-exit": false,
++        "x2apic": true,
++        "avx512vbmi": false,
++        "avx512vnni": false,
++        "vmx-apicv-x2apic": true,
++        "kvm-pv-sched-yield": true,
++        "hv-stimer": false,
++        "vmx-invlpg-exit": true,
++        "x-hv-synic-kvm-only": true,
++        "vmx-invvpid-all-context": true,
++        "i64": true,
++        "vmx-activity-hlt": true,
++        "flushbyasid": false,
++        "f16c": false,
++        "vmx-exit-ack-intr": true,
++        "ace2-en": false,
++        "pat": true,
++        "pae": true,
++        "sse": true,
++        "die-id": -1,
++        "vmx-tsc-offset": true,
++        "phe-en": false,
++        "kvm_nopiodelay": true,
++        "kvm-nopiodelay": true,
++        "tm": false,
++        "kvmclock-stable-bit": true,
++        "vmx-rdtsc-exit": true,
++        "hypervisor": true,
++        "vmx-rdtscp-exit": true,
++        "socket-id": -1,
++        "mds-no": true,
++        "pcommit": false,
++        "vmx-vpid": true,
++        "syscall": true,
++        "level": 27,
++        "avx512dq": false,
++        "x-migrate-smi-count": false,
++        "svm": false,
++        "full-cpuid-auto-level": true,
++        "hv-reset": false,
++        "invtsc": false,
++        "vmx-monitor-exit": true,
++        "sse3": true,
++        "sse2": true,
++        "vmx-wbinvd-exit": true,
++        "ssbd": true,
++        "est": false,
++        "kvm-poll-control": true,
++        "kvm_poll_control": true,
++        "avx512ifma": false,
++        "tm2": false,
++        "kvm-pv-ipi": true,
++        "kvm-pv-eoi": true,
++        "cx8": true,
++        "vmx-invvpid-single-addr": true,
++        "waitpkg": false,
++        "cldemote": true,
++        "vmx-ept": true,
++        "hv-reenlightenment": false,
++        "kvm_mmu": false,
++        "kvm-mmu": false,
++        "sse4_2": true,
++        "sse4.2": true,
++        "sse4-2": true,
++        "pge": true,
++        "fill-mtrr-mask": true,
++        "avx512bitalg": false,
++        "nodeid_msr": false,
++        "vmx-entry-load-bndcfgs": false,
++        "pdcm": true,
++        "vmx-exit-clear-rtit-ctl": false,
++        "movbe": true,
++        "model": 134,
++        "nrip_save": false,
++        "nrip-save": false,
++        "kvm_pv_unhalt": true,
++        "ssse3": true,
++        "sse4a": false,
++        "vmx-pause-exit": true,
++        "invpcid": false,
++        "pdpe1gb": false,
++        "tsc-deadline": true,
++        "skip-l1dfl-vmentry": true,
++        "vmx-exit-load-perf-global-ctrl": false,
++        "fma": false,
++        "cx16": true,
++        "de": true,
++        "enforce": false,
++        "stepping": 5,
++        "xsave": true,
++        "clflush": true,
++        "skinit": false,
++        "tsc": true,
++        "tce": false,
++        "fpu": true,
++        "ibs": false,
++        "ds_cpl": false,
++        "ds-cpl": false,
++        "vmx-exit-nosave-debugctl": true,
++        "host-phys-bits": true,
++        "fma4": false,
++        "vmx-invept": true,
++        "la57": false,
++        "osvw": false,
++        "check": true,
++        "hv-spinlocks": 4294967295,
++        "vmx-eptad": true,
++        "pmu": false,
++        "pmm": false,
++        "apic": true,
++        "vmx-entry-noload-debugctl": true,
++        "spec-ctrl": true,
++        "vmx-posted-intr": true,
++        "vmx-apicv-register": true,
++        "min-xlevel2": 0,
++        "tsc-adjust": true,
++        "tsc_adjust": true,
++        "kvm-steal-time": true,
++        "kvm_steal_time": true,
++        "vmx-zero-len-inject": false,
++        "kvmclock": true,
++        "pschange-mc-no": true,
++        "l3-cache": true,
++        "vmx-rdrand-exit": true,
++        "lwp": false,
++        "hv-passthrough": false,
++        "amd-ssbd": true,
++        "ibpb": true,
++        "xop": false,
++        "avx": false,
++        "core-capability": false,
++        "vmx-invept-single-context": true,
++        "movdiri": true,
++        "ace2": false,
++        "avx512bw": false,
++        "acpi": false,
++        "hv-vapic": false,
++        "fsgsbase": true,
++        "vmx-ept-1gb": true,
++        "vmx-ept-2mb": true,
++        "ht": false,
++        "vmx-io-exit": true,
++        "nx": true,
++        "pclmulqdq": true,
++        "mmxext": false,
++        "vaes": false,
++        "popcnt": true,
++        "xsaves": true,
++        "movdir64b": true,
++        "tcg-cpuid": true,
++        "vmx-shadow-vmcs": true,
++        "lm": true,
++        "vmx-exit-save-preemption-timer": true,
++        "vmx-entry-load-pat": true,
++        "vmx-entry-load-perf-global-ctrl": false,
++        "vmx-io-bitmap": true,
++        "umip": true,
++        "vmx-store-lma": true,
++        "vmx-movdr-exit": true,
++        "pse": true,
++        "avx2": false,
++        "sep": true,
++        "pclmuldq": true,
++        "virt-ssbd": false,
++        "vmx-cr3-load-noexit": true,
++        "x-hv-max-vps": -1,
++        "nodeid-msr": false,
++        "md-clear": true,
++        "split-lock-detect": false,
++        "kvm": true,
++        "misalignsse": false,
++        "min-xlevel": 2147483656,
++        "kvm-pv-unhalt": true,
++        "bmi2": false,
++        "bmi1": false,
++        "realized": false,
++        "tsc_scale": false,
++        "tsc-scale": false,
++        "topoext": false,
++        "hv-vpindex": false,
++        "hv-no-nonarch-coresharing": "off",
++        "amd-stibp": true,
++        "vmx-preemption-timer": true,
++        "ucode-rev": 0,
++        "xlevel2": 0,
++        "clflushopt": true,
++        "vmx-vnmi-pending": true,
++        "kvm-no-smi-migration": false,
++        "monitor": false,
++        "vmx-vintr-pending": true,
++        "avx512er": false,
++        "pmm-en": false,
++        "pcid": false,
++        "taa-no": false,
++        "vmx-secondary-ctls": true,
++        "arch-capabilities": true,
++        "vmx-xsaves": true,
++        "clzero": false,
++        "3dnow": false,
++        "erms": true,
++        "vmx-entry-ia32e-mode": true,
++        "x-force-features": false,
++        "lahf_lm": true,
++        "lahf-lm": true,
++        "vpclmulqdq": false,
++        "vmx-ins-outs": true,
++        "fxsr-opt": false,
++        "hv-synic": false,
++        "xstore": false,
++        "fxsr_opt": false,
++        "kvm-hint-dedicated": false,
++        "rtm": false,
++        "lmce": true,
++        "hv-time": false,
++        "perfctr-nb": false,
++        "perfctr_nb": false,
++        "ffxsr": false,
++        "hv-tlbflush": false,
++        "rdrand": true,
++        "rdseed": true,
++        "avx512-4vnniw": false,
++        "vmx": true,
++        "vme": true,
++        "dtes64": false,
++        "mtrr": true,
++        "rdtscp": true,
++        "xsaveerptr": false,
++        "pse36": true,
++        "kvm-pv-tlb-flush": true,
++        "vmx-activity-wait-sipi": false,
++        "tbm": false,
++        "wdt": false,
++        "vmx-rdpmc-exit": true,
++        "level-func7": 0,
++        "vmx-entry-load-efer": true,
++        "vmx-mtf": true,
++        "pause_filter": false,
++        "sha-ni": true,
++        "model-id": "Intel Atom(R) P5362 processor",
++        "abm": false,
++        "vmx-ept-advanced-exitinfo": false,
++        "avx512pf": false,
++        "vmx-hlt-exit": true,
++        "xstore-en": false
++      }
++    }
++  },
++  "id": "model-expansion"
++}
++
++{
++  "return": [
++    {
++      "name": "max",
++      "typename": "max-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": false
++    },
++    {
++      "name": "host",
++      "typename": "host-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": false
++    },
++    {
++      "name": "base",
++      "typename": "base-x86_64-cpu",
++      "unavailable-features": [],
++      "static": true,
++      "migration-safe": true
++    },
++    {
++      "name": "qemu64-v1",
++      "typename": "qemu64-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "qemu64",
++      "typename": "qemu64-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "qemu32-v1",
++      "typename": "qemu32-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "qemu32",
++      "typename": "qemu32-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "phenom-v1",
++      "typename": "phenom-v1-x86_64-cpu",
++      "unavailable-features": [
++        "mmxext",
++        "fxsr-opt",
++        "pdpe1gb",
++        "3dnowext",
++        "3dnow",
++        "abm",
++        "sse4a"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "phenom",
++      "typename": "phenom-x86_64-cpu",
++      "unavailable-features": [
++        "mmxext",
++        "fxsr-opt",
++        "pdpe1gb",
++        "3dnowext",
++        "3dnow",
++        "abm",
++        "sse4a"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "pentium3-v1",
++      "typename": "pentium3-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "pentium3",
++      "typename": "pentium3-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "pentium2-v1",
++      "typename": "pentium2-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "pentium2",
++      "typename": "pentium2-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "pentium-v1",
++      "typename": "pentium-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "pentium",
++      "typename": "pentium-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "n270-v1",
++      "typename": "n270-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "n270",
++      "typename": "n270-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "kvm64-v1",
++      "typename": "kvm64-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "kvm64",
++      "typename": "kvm64-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "kvm32-v1",
++      "typename": "kvm32-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "kvm32",
++      "typename": "kvm32-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "coreduo-v1",
++      "typename": "coreduo-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "coreduo",
++      "typename": "coreduo-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "core2duo-v1",
++      "typename": "core2duo-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "core2duo",
++      "typename": "core2duo-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "athlon-v1",
++      "typename": "athlon-v1-x86_64-cpu",
++      "unavailable-features": [
++        "mmxext",
++        "3dnowext",
++        "3dnow"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "athlon",
++      "typename": "athlon-x86_64-cpu",
++      "unavailable-features": [
++        "mmxext",
++        "3dnowext",
++        "3dnow"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Westmere-v2",
++      "typename": "Westmere-v2-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Westmere-v1",
++      "typename": "Westmere-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Westmere-IBRS",
++      "typename": "Westmere-IBRS-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Westmere",
++      "typename": "Westmere-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Snowridge-v2",
++      "typename": "Snowridge-v2-x86_64-cpu",
++      "unavailable-features": [
++        "core-capability",
++        "pdpe1gb",
++        "split-lock-detect"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Snowridge-v1",
++      "typename": "Snowridge-v1-x86_64-cpu",
++      "unavailable-features": [
++        "mpx",
++        "core-capability",
++        "pdpe1gb",
++        "mpx",
++        "mpx",
++        "split-lock-detect"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Snowridge",
++      "typename": "Snowridge-x86_64-cpu",
++      "unavailable-features": [
++        "mpx",
++        "core-capability",
++        "pdpe1gb",
++        "mpx",
++        "mpx",
++        "split-lock-detect"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Server-v3",
++      "typename": "Skylake-Server-v3-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Server-v2",
++      "typename": "Skylake-Server-v2-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Server-v1",
++      "typename": "Skylake-Server-v1-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Server-noTSX-IBRS",
++      "typename": "Skylake-Server-noTSX-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Server-IBRS",
++      "typename": "Skylake-Server-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "mpx",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "mpx",
++        "mpx",
++        "avx512f",
++        "avx512f",
++        "avx512f"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Server",
++      "typename": "Skylake-Server-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "mpx",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "mpx",
++        "mpx",
++        "avx512f",
++        "avx512f",
++        "avx512f"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Client-v3",
++      "typename": "Skylake-Client-v3-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "adx",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Client-v2",
++      "typename": "Skylake-Client-v2-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "adx",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Client-v1",
++      "typename": "Skylake-Client-v1-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "adx",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Client-noTSX-IBRS",
++      "typename": "Skylake-Client-noTSX-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "adx",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Client-IBRS",
++      "typename": "Skylake-Client-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "mpx",
++        "adx",
++        "abm",
++        "avx",
++        "mpx",
++        "mpx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Skylake-Client",
++      "typename": "Skylake-Client-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "mpx",
++        "adx",
++        "abm",
++        "avx",
++        "mpx",
++        "mpx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "SandyBridge-v2",
++      "typename": "SandyBridge-v2-x86_64-cpu",
++      "unavailable-features": [
++        "avx",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "SandyBridge-v1",
++      "typename": "SandyBridge-v1-x86_64-cpu",
++      "unavailable-features": [
++        "avx",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "SandyBridge-IBRS",
++      "typename": "SandyBridge-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "avx",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "SandyBridge",
++      "typename": "SandyBridge-x86_64-cpu",
++      "unavailable-features": [
++        "avx",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Penryn-v1",
++      "typename": "Penryn-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Penryn",
++      "typename": "Penryn-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G5-v1",
++      "typename": "Opteron_G5-v1-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "avx",
++        "f16c",
++        "pdpe1gb",
++        "abm",
++        "sse4a",
++        "misalignsse",
++        "xop",
++        "fma4",
++        "tbm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G5",
++      "typename": "Opteron_G5-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "avx",
++        "f16c",
++        "pdpe1gb",
++        "abm",
++        "sse4a",
++        "misalignsse",
++        "xop",
++        "fma4",
++        "tbm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G4-v1",
++      "typename": "Opteron_G4-v1-x86_64-cpu",
++      "unavailable-features": [
++        "avx",
++        "pdpe1gb",
++        "abm",
++        "sse4a",
++        "misalignsse",
++        "xop",
++        "fma4",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G4",
++      "typename": "Opteron_G4-x86_64-cpu",
++      "unavailable-features": [
++        "avx",
++        "pdpe1gb",
++        "abm",
++        "sse4a",
++        "misalignsse",
++        "xop",
++        "fma4",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G3-v1",
++      "typename": "Opteron_G3-v1-x86_64-cpu",
++      "unavailable-features": [
++        "abm",
++        "sse4a",
++        "misalignsse"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G3",
++      "typename": "Opteron_G3-x86_64-cpu",
++      "unavailable-features": [
++        "abm",
++        "sse4a",
++        "misalignsse"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G2-v1",
++      "typename": "Opteron_G2-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G2",
++      "typename": "Opteron_G2-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G1-v1",
++      "typename": "Opteron_G1-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Opteron_G1",
++      "typename": "Opteron_G1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Nehalem-v2",
++      "typename": "Nehalem-v2-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Nehalem-v1",
++      "typename": "Nehalem-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Nehalem-IBRS",
++      "typename": "Nehalem-IBRS-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Nehalem",
++      "typename": "Nehalem-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "KnightsMill-v1",
++      "typename": "KnightsMill-v1-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "avx512f",
++        "adx",
++        "avx512pf",
++        "avx512er",
++        "avx512cd",
++        "avx512-vpopcntdq",
++        "avx512-4vnniw",
++        "avx512-4fmaps",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "KnightsMill",
++      "typename": "KnightsMill-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "avx512f",
++        "adx",
++        "avx512pf",
++        "avx512er",
++        "avx512cd",
++        "avx512-vpopcntdq",
++        "avx512-4vnniw",
++        "avx512-4fmaps",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "IvyBridge-v2",
++      "typename": "IvyBridge-v2-x86_64-cpu",
++      "unavailable-features": [
++        "avx",
++        "f16c",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "IvyBridge-v1",
++      "typename": "IvyBridge-v1-x86_64-cpu",
++      "unavailable-features": [
++        "avx",
++        "f16c",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "IvyBridge-IBRS",
++      "typename": "IvyBridge-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "avx",
++        "f16c",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "IvyBridge",
++      "typename": "IvyBridge-x86_64-cpu",
++      "unavailable-features": [
++        "avx",
++        "f16c",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Server-v3",
++      "typename": "Icelake-Server-v3-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "la57",
++        "pdpe1gb",
++        "abm",
++        "wbnoinvd",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku",
++        "taa-no"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Server-v2",
++      "typename": "Icelake-Server-v2-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "la57",
++        "pdpe1gb",
++        "abm",
++        "wbnoinvd",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Server-v1",
++      "typename": "Icelake-Server-v1-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "la57",
++        "pdpe1gb",
++        "abm",
++        "wbnoinvd",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Server-noTSX",
++      "typename": "Icelake-Server-noTSX-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "la57",
++        "pdpe1gb",
++        "abm",
++        "wbnoinvd",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Server",
++      "typename": "Icelake-Server-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "mpx",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "la57",
++        "pdpe1gb",
++        "abm",
++        "wbnoinvd",
++        "avx",
++        "mpx",
++        "mpx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Client-v2",
++      "typename": "Icelake-Client-v2-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "adx",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "abm",
++        "wbnoinvd",
++        "avx",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Client-v1",
++      "typename": "Icelake-Client-v1-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "adx",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "abm",
++        "wbnoinvd",
++        "avx",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Client-noTSX",
++      "typename": "Icelake-Client-noTSX-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "adx",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "abm",
++        "wbnoinvd",
++        "avx",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Icelake-Client",
++      "typename": "Icelake-Client-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "mpx",
++        "adx",
++        "avx512vbmi",
++        "pku",
++        "avx512vbmi2",
++        "vaes",
++        "vpclmulqdq",
++        "avx512vnni",
++        "avx512bitalg",
++        "avx512-vpopcntdq",
++        "abm",
++        "wbnoinvd",
++        "avx",
++        "mpx",
++        "mpx",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell-v4",
++      "typename": "Haswell-v4-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell-v3",
++      "typename": "Haswell-v3-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell-v2",
++      "typename": "Haswell-v2-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell-v1",
++      "typename": "Haswell-v1-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell-noTSX-IBRS",
++      "typename": "Haswell-noTSX-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell-noTSX",
++      "typename": "Haswell-noTSX-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell-IBRS",
++      "typename": "Haswell-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Haswell",
++      "typename": "Haswell-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "EPYC-v2",
++      "typename": "EPYC-v2-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "adx",
++        "mmxext",
++        "fxsr-opt",
++        "pdpe1gb",
++        "cr8legacy",
++        "abm",
++        "sse4a",
++        "misalignsse",
++        "osvw",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "EPYC-v1",
++      "typename": "EPYC-v1-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "adx",
++        "mmxext",
++        "fxsr-opt",
++        "pdpe1gb",
++        "cr8legacy",
++        "abm",
++        "sse4a",
++        "misalignsse",
++        "osvw",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "EPYC-Rome-v1",
++      "typename": "EPYC-Rome-v1-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "adx",
++        "mmxext",
++        "fxsr-opt",
++        "pdpe1gb",
++        "cr8legacy",
++        "abm",
++        "sse4a",
++        "misalignsse",
++        "osvw",
++        "perfctr-core",
++        "clzero",
++        "xsaveerptr",
++        "wbnoinvd",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "EPYC-Rome",
++      "typename": "EPYC-Rome-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "adx",
++        "mmxext",
++        "fxsr-opt",
++        "pdpe1gb",
++        "cr8legacy",
++        "abm",
++        "sse4a",
++        "misalignsse",
++        "osvw",
++        "perfctr-core",
++        "clzero",
++        "xsaveerptr",
++        "wbnoinvd",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "EPYC-IBPB",
++      "typename": "EPYC-IBPB-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "adx",
++        "mmxext",
++        "fxsr-opt",
++        "pdpe1gb",
++        "cr8legacy",
++        "abm",
++        "sse4a",
++        "misalignsse",
++        "osvw",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "EPYC",
++      "typename": "EPYC-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "adx",
++        "mmxext",
++        "fxsr-opt",
++        "pdpe1gb",
++        "cr8legacy",
++        "abm",
++        "sse4a",
++        "misalignsse",
++        "osvw",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Dhyana-v1",
++      "typename": "Dhyana-v1-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "adx",
++        "mmxext",
++        "fxsr-opt",
++        "pdpe1gb",
++        "cr8legacy",
++        "abm",
++        "sse4a",
++        "misalignsse",
++        "osvw",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Dhyana",
++      "typename": "Dhyana-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "adx",
++        "mmxext",
++        "fxsr-opt",
++        "pdpe1gb",
++        "cr8legacy",
++        "abm",
++        "sse4a",
++        "misalignsse",
++        "osvw",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Denverton-v1",
++      "typename": "Denverton-v1-x86_64-cpu",
++      "unavailable-features": [
++        "mpx",
++        "pdpe1gb",
++        "mpx",
++        "mpx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Denverton",
++      "typename": "Denverton-x86_64-cpu",
++      "unavailable-features": [
++        "mpx",
++        "pdpe1gb",
++        "mpx",
++        "mpx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Cooperlake-v1",
++      "typename": "Cooperlake-v1-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512vnni",
++        "avx512-bf16",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku",
++        "taa-no"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Cooperlake",
++      "typename": "Cooperlake-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512vnni",
++        "avx512-bf16",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku",
++        "taa-no"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Conroe-v1",
++      "typename": "Conroe-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Conroe",
++      "typename": "Conroe-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Cascadelake-Server-v3",
++      "typename": "Cascadelake-Server-v3-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512vnni",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Cascadelake-Server-v2",
++      "typename": "Cascadelake-Server-v2-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512vnni",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Cascadelake-Server-v1",
++      "typename": "Cascadelake-Server-v1-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512vnni",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Cascadelake-Server-noTSX",
++      "typename": "Cascadelake-Server-noTSX-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512vnni",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Cascadelake-Server",
++      "typename": "Cascadelake-Server-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "mpx",
++        "avx512f",
++        "avx512dq",
++        "adx",
++        "avx512cd",
++        "avx512bw",
++        "avx512vl",
++        "pku",
++        "avx512vnni",
++        "pdpe1gb",
++        "abm",
++        "avx",
++        "mpx",
++        "mpx",
++        "avx512f",
++        "avx512f",
++        "avx512f",
++        "pku"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell-v4",
++      "typename": "Broadwell-v4-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "adx",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell-v3",
++      "typename": "Broadwell-v3-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "adx",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell-v2",
++      "typename": "Broadwell-v2-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "adx",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell-v1",
++      "typename": "Broadwell-v1-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "adx",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell-noTSX-IBRS",
++      "typename": "Broadwell-noTSX-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "adx",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell-noTSX",
++      "typename": "Broadwell-noTSX-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "adx",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell-IBRS",
++      "typename": "Broadwell-IBRS-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "adx",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "Broadwell",
++      "typename": "Broadwell-x86_64-cpu",
++      "unavailable-features": [
++        "fma",
++        "pcid",
++        "avx",
++        "f16c",
++        "bmi1",
++        "hle",
++        "avx2",
++        "bmi2",
++        "invpcid",
++        "rtm",
++        "adx",
++        "abm",
++        "avx"
++      ],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "486-v1",
++      "typename": "486-v1-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    },
++    {
++      "name": "486",
++      "typename": "486-x86_64-cpu",
++      "unavailable-features": [],
++      "static": false,
++      "migration-safe": true
++    }
++  ],
++  "id": "definitions"
++}
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362.sig b/tests/cputestdata/x86_64-cpuid-Atom-P5362.sig
+new file mode 100644
+index 0000000000..788ae6efba
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362.sig
+@@ -0,0 +1,4 @@
++080665
++family:     6 (0x06)
++model:    134 (0x86)
++stepping:   5 (0x05)
+diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362.xml
+new file mode 100644
+index 0000000000..4fe97c0866
+--- /dev/null
++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362.xml
+@@ -0,0 +1,61 @@
++<!-- Intel Atom(R) P5362 processor -->
++<cpudata arch='x86'>
++  <cpuid eax_in='0x00000000' ecx_in='0x00' eax='0x0000001b' ebx='0x756e6547' ecx='0x6c65746e' edx='0x49656e69'/>
++  <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00080665' ebx='0x02800800' ecx='0x4ff8ebff' edx='0xbfebfbff'/>
++  <cpuid eax_in='0x00000002' ecx_in='0x00' eax='0x00feff01' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000003' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000004' ecx_in='0x00' eax='0xfc000121' ebx='0x01c0003f' ecx='0x0000003f' edx='0x00000000'/>
++  <cpuid eax_in='0x00000004' ecx_in='0x01' eax='0xfc000122' ebx='0x01c0003f' ecx='0x0000003f' edx='0x00000000'/>
++  <cpuid eax_in='0x00000004' ecx_in='0x02' eax='0xfc01c143' ebx='0x0440003f' ecx='0x00000fff' edx='0x00000000'/>
++  <cpuid eax_in='0x00000004' ecx_in='0x03' eax='0xfc1fc163' ebx='0x04c0003f' ecx='0x00002fff' edx='0x00000004'/>
++  <cpuid eax_in='0x00000005' ecx_in='0x00' eax='0x00000040' ebx='0x00000040' ecx='0x00000003' edx='0x00001020'/>
++  <cpuid eax_in='0x00000006' ecx_in='0x00' eax='0x00000075' ebx='0x00000002' ecx='0x00000009' edx='0x00000000'/>
++  <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x2394b2c3' ecx='0x1a400124' edx='0xfc000400'/>
++  <cpuid eax_in='0x00000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000009' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000a' ecx_in='0x00' eax='0x07300405' ebx='0x00000000' ecx='0x00000007' edx='0x00008603'/>
++  <cpuid eax_in='0x0000000b' ecx_in='0x00' eax='0x00000001' ebx='0x00000001' ecx='0x00000100' edx='0x00000002'/>
++  <cpuid eax_in='0x0000000b' ecx_in='0x01' eax='0x00000007' ebx='0x00000018' ecx='0x00000201' edx='0x00000002'/>
++  <cpuid eax_in='0x0000000c' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000d' ecx_in='0x00' eax='0x00000003' ebx='0x00000240' ecx='0x00000240' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x0000000f' ebx='0x00000240' ecx='0x00000100' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000d' ecx_in='0x08' eax='0x00000080' ebx='0x00000000' ecx='0x00000001' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000e' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000000f' ecx_in='0x00' eax='0x00000000' ebx='0x0000002f' ecx='0x00000000' edx='0x00000002'/>
++  <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000008' ebx='0x00003000' ecx='0x0000002f' edx='0x00000007'/>
++  <cpuid eax_in='0x00000010' ecx_in='0x00' eax='0x00000000' ebx='0x0000000e' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000010' ecx_in='0x01' eax='0x00000013' ebx='0x000c0000' ecx='0x00000004' edx='0x0000000d'/>
++  <cpuid eax_in='0x00000010' ecx_in='0x02' eax='0x00000011' ebx='0x00000000' ecx='0x00000004' edx='0x0000000d'/>
++  <cpuid eax_in='0x00000010' ecx_in='0x03' eax='0x00000059' ebx='0x00000000' ecx='0x00000004' edx='0x0000000d'/>
++  <cpuid eax_in='0x00000011' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000012' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000013' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000014' ecx_in='0x00' eax='0x00000001' ebx='0x0000007f' ecx='0x80000007' edx='0x00000000'/>
++  <cpuid eax_in='0x00000014' ecx_in='0x01' eax='0x02490002' ebx='0x003fffff' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000015' ecx_in='0x00' eax='0x00000002' ebx='0x000000b0' ecx='0x017d7840' edx='0x00000000'/>
++  <cpuid eax_in='0x00000016' ecx_in='0x00' eax='0x00000898' ebx='0x00000898' ecx='0x00000064' edx='0x00000000'/>
++  <cpuid eax_in='0x00000017' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000018' ecx_in='0x00' eax='0x00000005' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000018' ecx_in='0x01' eax='0x00000000' ebx='0x00300001' ecx='0x00000001' edx='0x00000121'/>
++  <cpuid eax_in='0x00000018' ecx_in='0x02' eax='0x00000000' ebx='0x00040001' ecx='0x00000100' edx='0x00000043'/>
++  <cpuid eax_in='0x00000018' ecx_in='0x03' eax='0x00000000' ebx='0x00040006' ecx='0x00000010' edx='0x00000043'/>
++  <cpuid eax_in='0x00000018' ecx_in='0x04' eax='0x00000000' ebx='0x00300001' ecx='0x00000001' edx='0x00000122'/>
++  <cpuid eax_in='0x00000018' ecx_in='0x05' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x00000019' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000001a' ecx_in='0x00' eax='0x20000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x0000001b' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x20000000' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000000' ecx_in='0x00' eax='0x80000008' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000101' edx='0x28100800'/>
++  <cpuid eax_in='0x80000002' ecx_in='0x00' eax='0x65746e49' ebx='0x7441206c' ecx='0x52286d6f' edx='0x35502029'/>
++  <cpuid eax_in='0x80000003' ecx_in='0x00' eax='0x20323633' ebx='0x636f7270' ecx='0x6f737365' edx='0x00000072'/>
++  <cpuid eax_in='0x80000004' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000005' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80000006' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x12008040' edx='0x00000000'/>
++  <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/>
++  <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x0000302a' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0x80860000' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <cpuid eax_in='0xc0000000' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/>
++  <msr index='0xcf' edx='0x00000000' eax='0x00000060'/>
++  <msr index='0x10a' edx='0x001a8c7f' eax='0xa080036b'/>
++</cpudata>
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-docs-use-proper-cpu-quota-value-in-our-documentation.patch b/SOURCES/libvirt-docs-use-proper-cpu-quota-value-in-our-documentation.patch
new file mode 100644
index 0000000..abe880f
--- /dev/null
+++ b/SOURCES/libvirt-docs-use-proper-cpu-quota-value-in-our-documentation.patch
@@ -0,0 +1,101 @@
+From c9113d8cd9d68c932175ea63b634fc5cb7e51ef2 Mon Sep 17 00:00:00 2001
+Message-Id: <c9113d8cd9d68c932175ea63b634fc5cb7e51ef2@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Thu, 4 Mar 2021 12:57:56 +0100
+Subject: [PATCH] docs: use proper cpu quota value in our documentation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit <d505b8af58912ae1e1a211fabc9995b19bd40828> changed the cpu quota
+value that reflects what kernel allows but did not update our
+documentation.
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 992635b142b261cedb6075e459918418fe6e6962)
+
+Conflicts:
+    docs/formatdomain.rst
+        - missing in downstream, we use formatdomain.html.in
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <ba20be50c3bde1668cb214253e5ef8f212fc062b.1614858616.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/formatdomain.html.in     | 8 ++++----
+ docs/manpages/virsh.rst       | 2 +-
+ docs/schemas/domaincommon.rng | 2 +-
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 127dd13cc0..4341e256a8 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -872,7 +872,7 @@
+         bandwidth (unit: microseconds). A domain with <code>quota</code> as any
+         negative value indicates that the domain has infinite bandwidth for
+         vCPU threads, which means that it is not bandwidth controlled. The value
+-        should be in range [1000, 18446744073709551] or less than 0. A quota
++        should be in range [1000, 17592186044415] or less than 0. A quota
+         with value 0 means no value. You can use this feature to ensure that all
+         vCPUs run at the same speed.
+         <span class="since">Only QEMU driver support since 0.9.4, LXC since
+@@ -894,7 +894,7 @@
+         domain. A domain with <code>global_quota</code> as any negative
+         value indicates that the domain has infinite bandwidth, which means that
+         it is not bandwidth controlled. The value should be in range
+-        [1000, 18446744073709551] or less than 0. A <code>global_quota</code>
++        [1000, 17592186044415] or less than 0. A <code>global_quota</code>
+         with value 0 means no value.
+         <span class="since">Only QEMU driver support since 1.3.3</span>
+       </dd>
+@@ -915,7 +915,7 @@
+         excluding vCPUs). A domain with <code>emulator_quota</code> as any negative
+         value indicates that the domain has infinite bandwidth for emulator threads
+         (those excluding vCPUs), which means that it is not bandwidth controlled.
+-        The value should be in range [1000, 18446744073709551] or less than 0. A
++        The value should be in range [1000, 17592186044415] or less than 0. A
+         quota with value 0 means no value.
+         <span class="since">Only QEMU driver support since 0.10.0</span>
+       </dd>
+@@ -937,7 +937,7 @@
+         <code>iothread_quota</code> as any negative value indicates that the
+         domain IOThreads have infinite bandwidth, which means that it is
+         not bandwidth controlled. The value should be in range
+-        [1000, 18446744073709551] or less than 0. An <code>iothread_quota</code>
++        [1000, 17592186044415] or less than 0. An <code>iothread_quota</code>
+         with value 0 means no value. You can use this feature to ensure that
+         all IOThreads run at the same speed.
+         <span class="since">Only QEMU driver support since 2.1.0</span>
+diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
+index 0804465d44..a5b95c1123 100644
+--- a/docs/manpages/virsh.rst
++++ b/docs/manpages/virsh.rst
+@@ -3715,7 +3715,7 @@ XEN_CREDIT scheduler.
+ ``Note``: The vcpu_period, emulator_period, and iothread_period parameters
+ have a valid value range of 1000-1000000 or 0, and the vcpu_quota,
+ emulator_quota, and iothread_quota parameters have a valid value range of
+-1000-18446744073709551 or less than 0. The value 0 for
++1000-17592186044415 or less than 0. The value 0 for
+ either parameter is the same as not specifying that parameter.
+ 
+ 
+diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
+index 4a42cb9b40..6671ef3dfa 100644
+--- a/docs/schemas/domaincommon.rng
++++ b/docs/schemas/domaincommon.rng
+@@ -6649,7 +6649,7 @@
+   <define name="cpuquota">
+     <data type="long">
+       <param name="pattern">-?[0-9]+</param>
+-      <param name="maxInclusive">18446744073709551</param>
++      <param name="maxInclusive">17592186044415</param>
+       <param name='minInclusive'>-1</param>
+     </data>
+   </define>
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-domain_validate-use-defines-for-cpu-period-and-quota-limits.patch b/SOURCES/libvirt-domain_validate-use-defines-for-cpu-period-and-quota-limits.patch
new file mode 100644
index 0000000..e293dd5
--- /dev/null
+++ b/SOURCES/libvirt-domain_validate-use-defines-for-cpu-period-and-quota-limits.patch
@@ -0,0 +1,85 @@
+From 499e3eb6bdca10a5fac9279261e32e64c28273bd Mon Sep 17 00:00:00 2001
+Message-Id: <499e3eb6bdca10a5fac9279261e32e64c28273bd@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Thu, 4 Mar 2021 12:57:55 +0100
+Subject: [PATCH] domain_validate: use defines for cpu period and quota limits
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commints <bc760f4d7c4f964fadcb2a73e126b0053e7a9b06> and
+<98a09ca48ed4fc011abf2aa290e02ce1b8f1bb5f> fixed the code to use
+defines instead of magic numbers but missed this place.
+
+Following commit <ed1ba69f5a8132f8c1e73d2a1f142d70de0b564a> changed
+the cpu quota limit to reflect what kernel actually allows so using
+the defines fixes XML validations as well.
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 22cae2ea4bad7e285ba19d536bd475f8b00841f8)
+
+Conflicts:
+    src/conf/domain_validate.c
+        - not present in downstream, the code is still part of
+          domain_conf.c
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <63a44700876e2bd59f276fcd8395abaff011b4c1.1614858616.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/domain_conf.c | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 166c3e48d2..9f6cdb0de8 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -34,6 +34,7 @@
+ #include "domain_addr.h"
+ #include "domain_conf.h"
+ #include "snapshot_conf.h"
++#include "vircgroup.h"
+ #include "viralloc.h"
+ #include "virxml.h"
+ #include "viruuid.h"
+@@ -6997,10 +6998,13 @@ virDomainDefLifecycleActionValidate(const virDomainDef *def)
+ #define CPUTUNE_VALIDATE_PERIOD(name) \
+     do { \
+         if (def->cputune.name > 0 && \
+-            (def->cputune.name < 1000 || def->cputune.name > 1000000)) { \
++            (def->cputune.name < VIR_CGROUP_CPU_PERIOD_MIN || \
++             def->cputune.name > VIR_CGROUP_CPU_PERIOD_MAX)) { \
+             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
+-                           _("Value of cputune '%s' must be in range " \
+-                           "[1000, 1000000]"), #name); \
++                           _("Value of cputune '%s' must be in range [%llu, %llu]"), \
++                           #name, \
++                           VIR_CGROUP_CPU_PERIOD_MIN, \
++                           VIR_CGROUP_CPU_PERIOD_MAX); \
+             return -1; \
+         } \
+     } while (0)
+@@ -7008,11 +7012,13 @@ virDomainDefLifecycleActionValidate(const virDomainDef *def)
+ #define CPUTUNE_VALIDATE_QUOTA(name) \
+     do { \
+         if (def->cputune.name > 0 && \
+-            (def->cputune.name < 1000 || \
+-            def->cputune.name > 18446744073709551LL)) { \
++            (def->cputune.name < VIR_CGROUP_CPU_QUOTA_MIN || \
++            def->cputune.name > VIR_CGROUP_CPU_QUOTA_MAX)) { \
+             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \
+-                           _("Value of cputune '%s' must be in range " \
+-                           "[1000, 18446744073709551]"), #name); \
++                           _("Value of cputune '%s' must be in range [%llu, %llu]"), \
++                           #name, \
++                           VIR_CGROUP_CPU_QUOTA_MIN, \
++                           VIR_CGROUP_CPU_QUOTA_MAX); \
+             return -1; \
+         } \
+     } while (0)
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-network-be-more-verbose-about-the-reason-for-a-firewall-reload.patch b/SOURCES/libvirt-network-be-more-verbose-about-the-reason-for-a-firewall-reload.patch
new file mode 100644
index 0000000..4499c36
--- /dev/null
+++ b/SOURCES/libvirt-network-be-more-verbose-about-the-reason-for-a-firewall-reload.patch
@@ -0,0 +1,57 @@
+From 3a0200ee7544307a9708a6e876603425647bad34 Mon Sep 17 00:00:00 2001
+Message-Id: <3a0200ee7544307a9708a6e876603425647bad34@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Fri, 15 Jan 2021 22:51:48 -0500
+Subject: [PATCH] network: be more verbose about the reason for a firewall
+ reload
+
+https://bugzilla.redhat.com/1607929
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit c102bbd3efc358fb44fa2bb37fb0bcbeaaab72a5)
+
+Conflicts: src/network/bridge_driver.c:
+    some minor things due to upstream switch to using glib for DBus
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20210116035151.1066734-6-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/network/bridge_driver.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
+index c9c45df758..5995396f78 100644
+--- a/src/network/bridge_driver.c
++++ b/src/network/bridge_driver.c
+@@ -665,6 +665,7 @@ firewalld_dbus_filter_bridge(DBusConnection *connection G_GNUC_UNUSED,
+     if (dbus_message_is_signal(message,
+                                "org.fedoraproject.FirewallD1", "Reloaded")) {
+         reload = true;
++        VIR_DEBUG("Reload in bridge_driver because of 'Reloaded' signal");
+ 
+     } else if (dbus_message_is_signal(message,
+                                       DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
+@@ -681,14 +682,15 @@ firewalld_dbus_filter_bridge(DBusConnection *connection G_GNUC_UNUSED,
+          * if new_owner is empty, firewalld is shutting down. If it is
+          * non-empty, then it is starting
+          */
+-        if (new_owner && *new_owner)
++        if (new_owner && *new_owner) {
++            VIR_DEBUG("Reload in bridge_driver because of 'NameOwnerChanged' signal, new owner is: '%s'",
++                      new_owner);
+             reload = true;
++        }
+     }
+ 
+-    if (reload) {
+-        VIR_DEBUG("Reload in bridge_driver because of firewalld.");
++    if (reload)
+         networkReloadFirewallRules(driver, false);
+-    }
+ 
+     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-node_device-detect-CSS-devices.patch b/SOURCES/libvirt-node_device-detect-CSS-devices.patch
new file mode 100644
index 0000000..a25595a
--- /dev/null
+++ b/SOURCES/libvirt-node_device-detect-CSS-devices.patch
@@ -0,0 +1,261 @@
+From 7604b24349c47ff008b1366eb19fc2959614fb71 Mon Sep 17 00:00:00 2001
+Message-Id: <7604b24349c47ff008b1366eb19fc2959614fb71@dist-git>
+From: Boris Fiuczynski <fiuczy@linux.ibm.com>
+Date: Thu, 8 Oct 2020 11:06:57 -0400
+Subject: [PATCH] node_device: detect CSS devices
+
+Make channel subsystem (CSS) devices available in the node_device driver.
+The CCS devices reside in the computer system and provide CCW devices, e.g.:
+
+  +- css_0_0_003a
+      |
+      +- ccw_0_0_1a2b
+          |
+          +- scsi_host0
+              |
+              +- scsi_target0_0_0
+                  |
+                  +- scsi_0_0_0_0
+
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
+Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
+(cherry picked from commit 05e6cdafa6e083a1d83e1f2e34b6472c60cc67ac)
+https://bugzilla.redhat.com/show_bug.cgi?id=1853289
+https://bugzilla.redhat.com/show_bug.cgi?id=1865932
+Message-Id: <20201008150700.52157-3-bfiuczyn@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+---
+ docs/schemas/nodedev.rng                      | 16 ++++++++++++++
+ src/conf/node_device_conf.c                   |  5 +++++
+ src/conf/node_device_conf.h                   |  1 +
+ src/conf/virnodedeviceobj.c                   |  1 +
+ src/node_device/node_device_udev.c            | 22 +++++++++++++++++++
+ .../ccw_0_0_10000-invalid.xml                 |  4 ++--
+ tests/nodedevschemadata/ccw_0_0_ffff.xml      |  4 ++--
+ tests/nodedevschemadata/css_0_0_ffff.xml      | 10 +++++++++
+ tests/nodedevxml2xmltest.c                    |  1 +
+ tools/virsh-nodedev.c                         |  1 +
+ 10 files changed, 61 insertions(+), 4 deletions(-)
+ create mode 100644 tests/nodedevschemadata/css_0_0_ffff.xml
+
+diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng
+index fe6ffa0b53..6ac5804bfb 100644
+--- a/docs/schemas/nodedev.rng
++++ b/docs/schemas/nodedev.rng
+@@ -85,6 +85,7 @@
+         <ref name="capdrm"/>
+         <ref name="capmdev"/>
+         <ref name="capccwdev"/>
++        <ref name="capcssdev"/>
+       </choice>
+     </element>
+   </define>
+@@ -651,6 +652,21 @@
+     </element>
+   </define>
+ 
++  <define name='capcssdev'>
++    <attribute name='type'>
++      <value>css</value>
++    </attribute>
++    <element name='cssid'>
++      <ref name='ccwCssidRange'/>
++    </element>
++    <element name='ssid'>
++      <ref name='ccwSsidRange'/>
++    </element>
++    <element name='devno'>
++      <ref name='ccwDevnoRange'/>
++    </element>
++  </define>
++
+   <define name='address'>
+     <element name='address'>
+       <attribute name='domain'><ref name='hexuint'/></attribute>
+diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
+index 4cf5b6e3d7..0a34faa29a 100644
+--- a/src/conf/node_device_conf.c
++++ b/src/conf/node_device_conf.c
+@@ -65,6 +65,7 @@ VIR_ENUM_IMPL(virNodeDevCap,
+               "mdev_types",
+               "mdev",
+               "ccw",
++              "css",
+ );
+ 
+ VIR_ENUM_IMPL(virNodeDevNetCap,
+@@ -588,6 +589,7 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def)
+                               data->mdev.iommuGroupNumber);
+             break;
+         case VIR_NODE_DEV_CAP_CCW_DEV:
++        case VIR_NODE_DEV_CAP_CSS_DEV:
+             virBufferAsprintf(&buf, "<cssid>0x%x</cssid>\n",
+                               data->ccw_dev.cssid);
+             virBufferAsprintf(&buf, "<ssid>0x%x</ssid>\n",
+@@ -1893,6 +1895,7 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt,
+         ret = virNodeDevCapMdevParseXML(ctxt, def, node, &caps->data.mdev);
+         break;
+     case VIR_NODE_DEV_CAP_CCW_DEV:
++    case VIR_NODE_DEV_CAP_CSS_DEV:
+         ret = virNodeDevCapCCWParseXML(ctxt, def, node, &caps->data.ccw_dev);
+         break;
+     case VIR_NODE_DEV_CAP_MDEV_TYPES:
+@@ -2211,6 +2214,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
+     case VIR_NODE_DEV_CAP_FC_HOST:
+     case VIR_NODE_DEV_CAP_VPORTS:
+     case VIR_NODE_DEV_CAP_CCW_DEV:
++    case VIR_NODE_DEV_CAP_CSS_DEV:
+     case VIR_NODE_DEV_CAP_LAST:
+         /* This case is here to shutup the compiler */
+         break;
+@@ -2264,6 +2268,7 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def)
+         case VIR_NODE_DEV_CAP_MDEV_TYPES:
+         case VIR_NODE_DEV_CAP_MDEV:
+         case VIR_NODE_DEV_CAP_CCW_DEV:
++        case VIR_NODE_DEV_CAP_CSS_DEV:
+         case VIR_NODE_DEV_CAP_LAST:
+             break;
+         }
+diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
+index bf7939fbb3..19ea3fc7c2 100644
+--- a/src/conf/node_device_conf.h
++++ b/src/conf/node_device_conf.h
+@@ -65,6 +65,7 @@ typedef enum {
+     VIR_NODE_DEV_CAP_MDEV_TYPES,        /* Device capable of mediated devices */
+     VIR_NODE_DEV_CAP_MDEV,              /* Mediated device */
+     VIR_NODE_DEV_CAP_CCW_DEV,           /* s390 CCW device */
++    VIR_NODE_DEV_CAP_CSS_DEV,           /* s390 channel subsystem device */
+ 
+     VIR_NODE_DEV_CAP_LAST
+ } virNodeDevCapType;
+diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c
+index 3a34a324ca..8c8ffd6d24 100644
+--- a/src/conf/virnodedeviceobj.c
++++ b/src/conf/virnodedeviceobj.c
+@@ -676,6 +676,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj,
+         case VIR_NODE_DEV_CAP_MDEV_TYPES:
+         case VIR_NODE_DEV_CAP_MDEV:
+         case VIR_NODE_DEV_CAP_CCW_DEV:
++        case VIR_NODE_DEV_CAP_CSS_DEV:
+         case VIR_NODE_DEV_CAP_LAST:
+             break;
+         }
+diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
+index 9667a042bd..efe3cebd6a 100644
+--- a/src/node_device/node_device_udev.c
++++ b/src/node_device/node_device_udev.c
+@@ -1097,6 +1097,24 @@ udevProcessCCW(struct udev_device *device,
+ }
+ 
+ 
++static int
++udevProcessCSS(struct udev_device *device,
++               virNodeDeviceDefPtr def)
++{
++    /* only process IO subchannel and vfio-ccw devices to keep the list sane */
++    if (STRNEQ(def->driver, "io_subchannel") &&
++        STRNEQ(def->driver, "vfio_ccw"))
++        return -1;
++
++    if (udevGetCCWAddress(def->sysfs_path, &def->caps->data) < 0)
++        return -1;
++
++    if (udevGenerateDeviceName(device, def, NULL) != 0)
++        return -1;
++
++    return 0;
++}
++
+ static int
+ udevGetDeviceNodes(struct udev_device *device,
+                    virNodeDeviceDefPtr def)
+@@ -1175,6 +1193,8 @@ udevGetDeviceType(struct udev_device *device,
+             *type = VIR_NODE_DEV_CAP_MDEV;
+         else if (STREQ_NULLABLE(subsystem, "ccw"))
+             *type = VIR_NODE_DEV_CAP_CCW_DEV;
++        else if (STREQ_NULLABLE(subsystem, "css"))
++            *type = VIR_NODE_DEV_CAP_CSS_DEV;
+ 
+         VIR_FREE(subsystem);
+     }
+@@ -1219,6 +1239,8 @@ udevGetDeviceDetails(struct udev_device *device,
+         return udevProcessMediatedDevice(device, def);
+     case VIR_NODE_DEV_CAP_CCW_DEV:
+         return udevProcessCCW(device, def);
++    case VIR_NODE_DEV_CAP_CSS_DEV:
++        return udevProcessCSS(device, def);
+     case VIR_NODE_DEV_CAP_MDEV_TYPES:
+     case VIR_NODE_DEV_CAP_SYSTEM:
+     case VIR_NODE_DEV_CAP_FC_HOST:
+diff --git a/tests/nodedevschemadata/ccw_0_0_10000-invalid.xml b/tests/nodedevschemadata/ccw_0_0_10000-invalid.xml
+index d840555c09..f3cf0c1c66 100644
+--- a/tests/nodedevschemadata/ccw_0_0_10000-invalid.xml
++++ b/tests/nodedevschemadata/ccw_0_0_10000-invalid.xml
+@@ -1,7 +1,7 @@
+ <device>
+   <name>ccw_0_0_10000</name>
+-  <path>/sys/devices/css0/0.0.0000/0.0.10000</path>
+-  <parent>computer</parent>
++  <path>/sys/devices/css0/0.0.0070/0.0.10000</path>
++  <parent>css_0_0_0070</parent>
+   <capability type='ccw'>
+     <cssid>0x0</cssid>
+     <ssid>0x0</ssid>
+diff --git a/tests/nodedevschemadata/ccw_0_0_ffff.xml b/tests/nodedevschemadata/ccw_0_0_ffff.xml
+index 5ecd0b0aae..3b8ea46e37 100644
+--- a/tests/nodedevschemadata/ccw_0_0_ffff.xml
++++ b/tests/nodedevschemadata/ccw_0_0_ffff.xml
+@@ -1,7 +1,7 @@
+ <device>
+   <name>ccw_0_0_ffff</name>
+-  <path>/sys/devices/css0/0.0.0000/0.0.ffff</path>
+-  <parent>computer</parent>
++  <path>/sys/devices/css0/0.0.0070/0.0.ffff</path>
++  <parent>css_0_0_0070</parent>
+   <capability type='ccw'>
+     <cssid>0x0</cssid>
+     <ssid>0x0</ssid>
+diff --git a/tests/nodedevschemadata/css_0_0_ffff.xml b/tests/nodedevschemadata/css_0_0_ffff.xml
+new file mode 100644
+index 0000000000..312e07fe65
+--- /dev/null
++++ b/tests/nodedevschemadata/css_0_0_ffff.xml
+@@ -0,0 +1,10 @@
++<device>
++  <name>css_0_0_ffff</name>
++  <path>/sys/devices/css0/0.0.ffff</path>
++  <parent>computer</parent>
++  <capability type='css'>
++    <cssid>0x0</cssid>
++    <ssid>0x0</ssid>
++    <devno>0xffff</devno>
++  </capability>
++</device>
+diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c
+index 6168c29c70..3cb23b1df4 100644
+--- a/tests/nodedevxml2xmltest.c
++++ b/tests/nodedevxml2xmltest.c
+@@ -123,6 +123,7 @@ mymain(void)
+     DO_TEST("pci_0000_02_10_7_mdev_types");
+     DO_TEST("mdev_3627463d_b7f0_4fea_b468_f1da537d301b");
+     DO_TEST("ccw_0_0_ffff");
++    DO_TEST("css_0_0_ffff");
+ 
+     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c
+index cb2fc26d1a..26b3acc608 100644
+--- a/tools/virsh-nodedev.c
++++ b/tools/virsh-nodedev.c
+@@ -461,6 +461,7 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)
+         case VIR_NODE_DEV_CAP_CCW_DEV:
+             flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV;
+             break;
++        case VIR_NODE_DEV_CAP_CSS_DEV:
+         case VIR_NODE_DEV_CAP_LAST:
+             break;
+         }
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-node_device-detect-DASD-devices.patch b/SOURCES/libvirt-node_device-detect-DASD-devices.patch
new file mode 100644
index 0000000..626d59f
--- /dev/null
+++ b/SOURCES/libvirt-node_device-detect-DASD-devices.patch
@@ -0,0 +1,76 @@
+From c83c1121508cc4283f372789398a909146803b72 Mon Sep 17 00:00:00 2001
+Message-Id: <c83c1121508cc4283f372789398a909146803b72@dist-git>
+From: Boris Fiuczynski <fiuczy@linux.ibm.com>
+Date: Thu, 8 Oct 2020 11:06:59 -0400
+Subject: [PATCH] node_device: detect DASD devices
+
+Make Direct Access Storage Devices (DASDs) available in the node_device driver.
+
+Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
+(cherry picked from commit 33bbf589dd739c48ff20d2120e8c4018d241d32f)
+https://bugzilla.redhat.com/show_bug.cgi?id=1853289
+https://bugzilla.redhat.com/show_bug.cgi?id=1865932
+Message-Id: <20201008150700.52157-5-bfiuczyn@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+---
+ src/node_device/node_device_udev.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
+index efe3cebd6a..b6b28bc35a 100644
+--- a/src/node_device/node_device_udev.c
++++ b/src/node_device/node_device_udev.c
+@@ -870,6 +870,19 @@ udevProcessSD(struct udev_device *device,
+ }
+ 
+ 
++static int
++udevProcessDASD(struct udev_device *device,
++                virNodeDeviceDefPtr def)
++{
++    virNodeDevCapStoragePtr storage = &def->caps->data.storage;
++
++    if (udevGetStringSysfsAttr(device, "device/uid", &storage->serial) < 0)
++        return -1;
++
++    return udevProcessDisk(device, def);
++}
++
++
+ /* This function exists to deal with the case in which a driver does
+  * not provide a device type in the usual place, but udev told us it's
+  * a storage device, and we can make a good guess at what kind of
+@@ -890,6 +903,19 @@ udevKludgeStorageType(virNodeDeviceDefPtr def)
+                   def->sysfs_path);
+         return 0;
+     }
++
++    /* For Direct Access Storage Devices (DASDs) there are
++     * currently no identifiers in udev besides ID_PATH. Since
++     * ID_TYPE=disk does not exist on DASDs they fall through
++     * the udevProcessStorage detection logic. */
++    if (STRPREFIX(def->caps->data.storage.block, "/dev/dasd")) {
++        def->caps->data.storage.drive_type = g_strdup("dasd");
++        VIR_DEBUG("Found storage type '%s' for device "
++                  "with sysfs path '%s'",
++                  def->caps->data.storage.drive_type,
++                  def->sysfs_path);
++        return 0;
++    }
+     VIR_DEBUG("Could not determine storage type "
+               "for device with sysfs path '%s'", def->sysfs_path);
+     return -1;
+@@ -977,6 +1003,8 @@ udevProcessStorage(struct udev_device *device,
+         ret = udevProcessFloppy(device, def);
+     } else if (STREQ(def->caps->data.storage.drive_type, "sd")) {
+         ret = udevProcessSD(device, def);
++    } else if (STREQ(def->caps->data.storage.drive_type, "dasd")) {
++        ret = udevProcessDASD(device, def);
+     } else {
+         VIR_DEBUG("Unsupported storage type '%s'",
+                   def->caps->data.storage.drive_type);
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-node_device-refactor-udevProcessCCW.patch b/SOURCES/libvirt-node_device-refactor-udevProcessCCW.patch
new file mode 100644
index 0000000..1b6621c
--- /dev/null
+++ b/SOURCES/libvirt-node_device-refactor-udevProcessCCW.patch
@@ -0,0 +1,76 @@
+From a89df2d899e6e93ab7bccdaa1afb130d01d9b286 Mon Sep 17 00:00:00 2001
+Message-Id: <a89df2d899e6e93ab7bccdaa1afb130d01d9b286@dist-git>
+From: Boris Fiuczynski <fiuczy@linux.ibm.com>
+Date: Thu, 8 Oct 2020 11:06:56 -0400
+Subject: [PATCH] node_device: refactor udevProcessCCW
+
+Refactor out CCW address parsing for later reuse.
+
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
+Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
+(cherry picked from commit 0e7f8bb6c1c3a63cf892f7afcd34fcb979ef0155)
+https://bugzilla.redhat.com/show_bug.cgi?id=1853289
+https://bugzilla.redhat.com/show_bug.cgi?id=1865932
+Message-Id: <20201008150700.52157-2-bfiuczyn@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+---
+ src/node_device/node_device_udev.c | 31 ++++++++++++++++++++----------
+ 1 file changed, 21 insertions(+), 10 deletions(-)
+
+diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
+index ae3d081e66..9667a042bd 100644
+--- a/src/node_device/node_device_udev.c
++++ b/src/node_device/node_device_udev.c
+@@ -1058,27 +1058,38 @@ udevProcessMediatedDevice(struct udev_device *dev,
+ 
+ 
+ static int
+-udevProcessCCW(struct udev_device *device,
+-               virNodeDeviceDefPtr def)
++udevGetCCWAddress(const char *sysfs_path,
++                  virNodeDevCapDataPtr data)
+ {
+-    int online;
+     char *p;
+-    virNodeDevCapDataPtr data = &def->caps->data;
+-
+-    /* process only online devices to keep the list sane */
+-    if (udevGetIntSysfsAttr(device, "online", &online, 0) < 0 || online != 1)
+-        return -1;
+ 
+-    if ((p = strrchr(def->sysfs_path, '/')) == NULL ||
++    if ((p = strrchr(sysfs_path, '/')) == NULL ||
+         virStrToLong_ui(p + 1, &p, 16, &data->ccw_dev.cssid) < 0 || p == NULL ||
+         virStrToLong_ui(p + 1, &p, 16, &data->ccw_dev.ssid) < 0 || p == NULL ||
+         virStrToLong_ui(p + 1, &p, 16, &data->ccw_dev.devno) < 0) {
+         virReportError(VIR_ERR_INTERNAL_ERROR,
+                        _("failed to parse the CCW address from sysfs path: '%s'"),
+-                       def->sysfs_path);
++                       sysfs_path);
+         return -1;
+     }
+ 
++    return 0;
++}
++
++
++static int
++udevProcessCCW(struct udev_device *device,
++               virNodeDeviceDefPtr def)
++{
++    int online;
++
++    /* process only online devices to keep the list sane */
++    if (udevGetIntSysfsAttr(device, "online", &online, 0) < 0 || online != 1)
++        return -1;
++
++    if (udevGetCCWAddress(def->sysfs_path, &def->caps->data) < 0)
++        return -1;
++
+     if (udevGenerateDeviceName(device, def, NULL) != 0)
+         return -1;
+ 
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-numa-expose-HMAT-APIs.patch b/SOURCES/libvirt-numa-expose-HMAT-APIs.patch
new file mode 100644
index 0000000..08b3549
--- /dev/null
+++ b/SOURCES/libvirt-numa-expose-HMAT-APIs.patch
@@ -0,0 +1,242 @@
+From f2670434261a395acfe97a9bd93bd55c6b3fb1f2 Mon Sep 17 00:00:00 2001
+Message-Id: <f2670434261a395acfe97a9bd93bd55c6b3fb1f2@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 7 Oct 2020 18:45:41 +0200
+Subject: [PATCH] numa: expose HMAT APIs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+These APIs will be used by QEMU driver when building the command
+line.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 11d8ca9794e80224d0634d67da86a20380c22ab5)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Conflicts:
+- src/conf/numa_conf.c:
+- src/conf/numa_conf.h: Both are context.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <ad394e2359bfbbff4c9d61ac2bf5faca1eba5943.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/numa_conf.c     | 139 +++++++++++++++++++++++++++++++++++++++
+ src/conf/numa_conf.h     |  28 ++++++++
+ src/libvirt_private.syms |   6 ++
+ 3 files changed, 173 insertions(+)
+
+diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c
+index c90fb01bb6..277a695d84 100644
+--- a/src/conf/numa_conf.c
++++ b/src/conf/numa_conf.c
+@@ -1800,3 +1800,142 @@ virDomainNumaGetMemorySize(virDomainNumaPtr numa)
+ 
+     return ret;
+ }
++
++
++bool
++virDomainNumaHasHMAT(const virDomainNuma *numa)
++{
++    size_t i;
++
++    if (!numa)
++        return false;
++
++    if (numa->ninterconnects)
++        return true;
++
++    for (i = 0; i < numa->nmem_nodes; i++) {
++        if (numa->mem_nodes[i].ncaches)
++            return true;
++    }
++
++    return false;
++}
++
++
++size_t
++virDomainNumaGetNodeCacheCount(const virDomainNuma *numa,
++                               size_t node)
++{
++    if (!numa || node >= numa->nmem_nodes)
++        return 0;
++
++    return numa->mem_nodes[node].ncaches;
++}
++
++
++int
++virDomainNumaGetNodeCache(const virDomainNuma *numa,
++                          size_t node,
++                          size_t cache,
++                          unsigned int *level,
++                          unsigned int *size,
++                          unsigned int *line,
++                          virDomainCacheAssociativity *associativity,
++                          virDomainCachePolicy *policy)
++{
++    const virDomainNumaNode *cell;
++
++    if (!numa || node >= numa->nmem_nodes)
++        return -1;
++
++    cell = &numa->mem_nodes[node];
++
++    if (cache >= cell->ncaches)
++        return -1;
++
++    *level = cell->caches[cache].level;
++    *size = cell->caches[cache].size;
++    *line = cell->caches[cache].line;
++    *associativity = cell->caches[cache].associativity;
++    *policy = cell->caches[cache].policy;
++    return 0;
++}
++
++
++ssize_t
++virDomainNumaGetNodeInitiator(const virDomainNuma *numa,
++                              size_t node)
++{
++    size_t i;
++    unsigned int maxBandwidth = 0;
++    ssize_t candidateBandwidth = -1;
++    unsigned int minLatency = UINT_MAX;
++    ssize_t candidateLatency = -1;
++
++    if (!numa || node >= numa->nmem_nodes)
++        return -1;
++
++    for (i = 0; i < numa->ninterconnects; i++) {
++        const virDomainNumaInterconnect *l = &numa->interconnects[i];
++
++        if (l->target != node)
++            continue;
++
++        switch (l->type) {
++        case VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_LATENCY:
++            if (l->value < minLatency) {
++                minLatency = l->value;
++                candidateLatency = l->initiator;
++            }
++            break;
++
++        case VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_BANDWIDTH:
++            if (l->value > maxBandwidth) {
++                maxBandwidth = l->value;
++                candidateBandwidth = l->initiator;
++            }
++            break;
++        }
++    }
++
++    if (candidateLatency >= 0)
++        return candidateLatency;
++
++    return candidateBandwidth;
++}
++
++
++size_t
++virDomainNumaGetInterconnectsCount(const virDomainNuma *numa)
++{
++    if (!numa)
++        return 0;
++
++    return numa->ninterconnects;
++}
++
++
++int
++virDomainNumaGetInterconnect(const virDomainNuma *numa,
++                             size_t i,
++                             virDomainNumaInterconnectType *type,
++                             unsigned int *initiator,
++                             unsigned int *target,
++                             unsigned int *cache,
++                             virDomainMemoryLatency *accessType,
++                             unsigned long *value)
++{
++    const virDomainNumaInterconnect *l;
++
++    if (!numa || i >= numa->ninterconnects)
++        return -1;
++
++    l = &numa->interconnects[i];
++    *type = l->type;
++    *initiator = l->initiator;
++    *target = l->target;
++    *cache = l->cache;
++    *accessType = l->accessType;
++    *value = l->value;
++    return 0;
++}
+diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h
+index 2963004c94..63843a1cc6 100644
+--- a/src/conf/numa_conf.h
++++ b/src/conf/numa_conf.h
+@@ -220,3 +220,31 @@ int virDomainNumaDefFormatXML(virBufferPtr buf, virDomainNumaPtr def);
+ int virDomainNumaDefValidate(const virDomainNuma *def);
+ 
+ unsigned int virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa);
++
++bool virDomainNumaHasHMAT(const virDomainNuma *numa);
++
++size_t virDomainNumaGetNodeCacheCount(const virDomainNuma *numa,
++                                       size_t node);
++
++int virDomainNumaGetNodeCache(const virDomainNuma *numa,
++                              size_t node,
++                              size_t cache,
++                              unsigned int *level,
++                              unsigned int *size,
++                              unsigned int *line,
++                              virDomainCacheAssociativity *associativity,
++                              virDomainCachePolicy *policy);
++
++ssize_t virDomainNumaGetNodeInitiator(const virDomainNuma *numa,
++                                      size_t node);
++
++size_t virDomainNumaGetInterconnectsCount(const virDomainNuma *numa);
++
++int virDomainNumaGetInterconnect(const virDomainNuma *numa,
++                                 size_t i,
++                                 virDomainNumaInterconnectType *type,
++                                 unsigned int *initiator,
++                                 unsigned int *target,
++                                 unsigned int *cache,
++                                 virDomainMemoryLatency *accessType,
++                                 unsigned long *value);
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index de95e3b116..fdd104cd25 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -820,14 +820,20 @@ virDomainNumaCheckABIStability;
+ virDomainNumaEquals;
+ virDomainNumaFree;
+ virDomainNumaGetCPUCountTotal;
++virDomainNumaGetInterconnect;
++virDomainNumaGetInterconnectsCount;
+ virDomainNumaGetMaxCPUID;
+ virDomainNumaGetMemorySize;
++virDomainNumaGetNodeCache;
++virDomainNumaGetNodeCacheCount;
+ virDomainNumaGetNodeCount;
+ virDomainNumaGetNodeCpumask;
+ virDomainNumaGetNodeDiscard;
+ virDomainNumaGetNodeDistance;
++virDomainNumaGetNodeInitiator;
+ virDomainNumaGetNodeMemoryAccessMode;
+ virDomainNumaGetNodeMemorySize;
++virDomainNumaHasHMAT;
+ virDomainNumaNew;
+ virDomainNumaNodeDistanceIsUsingDefaults;
+ virDomainNumaNodesDistancesAreBeingSet;
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-numa_conf-Drop-CPU-from-name-of-two-functions.patch b/SOURCES/libvirt-numa_conf-Drop-CPU-from-name-of-two-functions.patch
new file mode 100644
index 0000000..2974deb
--- /dev/null
+++ b/SOURCES/libvirt-numa_conf-Drop-CPU-from-name-of-two-functions.patch
@@ -0,0 +1,102 @@
+From c049804bc3b296a183ce0bd819d5f9b1d1a45ea7 Mon Sep 17 00:00:00 2001
+Message-Id: <c049804bc3b296a183ce0bd819d5f9b1d1a45ea7@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 7 Oct 2020 18:45:34 +0200
+Subject: [PATCH] numa_conf: Drop CPU from name of two functions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There are two functions virDomainNumaDefCPUFormatXML() and
+virDomainNumaDefCPUParseXML() which format and parse domain's
+<numa/>. There is nothing CPU specific about them. Drop the
+infix.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 68c5b0183cb157c4672a6af3a14375df4434cee5)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Conflicts:
+- src/conf/domain_conf.c: Context.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <a06547d5b53c7a8fa2a2801a9cbd7a47834ebaa3.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/cpu_conf.c    | 2 +-
+ src/conf/domain_conf.c | 2 +-
+ src/conf/numa_conf.c   | 8 ++++----
+ src/conf/numa_conf.h   | 4 ++--
+ 4 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
+index 1a2948ce11..dfd0c1f798 100644
+--- a/src/conf/cpu_conf.c
++++ b/src/conf/cpu_conf.c
+@@ -746,7 +746,7 @@ virCPUDefFormatBufFull(virBufferPtr buf,
+     if (virCPUDefFormatBuf(&childrenBuf, def) < 0)
+         goto cleanup;
+ 
+-    if (virDomainNumaDefCPUFormatXML(&childrenBuf, numa) < 0)
++    if (virDomainNumaDefFormatXML(&childrenBuf, numa) < 0)
+         goto cleanup;
+ 
+     /* Put it all together */
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 484f3b4352..3229d5ec95 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -20487,7 +20487,7 @@ virDomainDefParseXML(xmlDocPtr xml,
+     if (virCPUDefParseXML(ctxt, "./cpu[1]", VIR_CPU_TYPE_GUEST, &def->cpu) < 0)
+         goto error;
+ 
+-    if (virDomainNumaDefCPUParseXML(def->numa, ctxt) < 0)
++    if (virDomainNumaDefParseXML(def->numa, ctxt) < 0)
+         goto error;
+ 
+     if (virDomainNumaGetCPUCountTotal(def->numa) > virDomainDefGetVcpusMax(def)) {
+diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c
+index 6f1257fd8e..38fcf9d9aa 100644
+--- a/src/conf/numa_conf.c
++++ b/src/conf/numa_conf.c
+@@ -842,8 +842,8 @@ virDomainNumaDefNodeDistanceParseXML(virDomainNumaPtr def,
+ }
+ 
+ int
+-virDomainNumaDefCPUParseXML(virDomainNumaPtr def,
+-                            xmlXPathContextPtr ctxt)
++virDomainNumaDefParseXML(virDomainNumaPtr def,
++                         xmlXPathContextPtr ctxt)
+ {
+     xmlNodePtr *nodes = NULL;
+     xmlNodePtr oldNode = ctxt->node;
+@@ -971,8 +971,8 @@ virDomainNumaDefCPUParseXML(virDomainNumaPtr def,
+ 
+ 
+ int
+-virDomainNumaDefCPUFormatXML(virBufferPtr buf,
+-                             virDomainNumaPtr def)
++virDomainNumaDefFormatXML(virBufferPtr buf,
++                          virDomainNumaPtr def)
+ {
+     virDomainMemoryAccess memAccess;
+     virTristateBool discard;
+diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h
+index b1b8e3274d..ce865cbfbb 100644
+--- a/src/conf/numa_conf.h
++++ b/src/conf/numa_conf.h
+@@ -182,7 +182,7 @@ bool virDomainNumatuneNodesetIsAvailable(virDomainNumaPtr numatune,
+ bool virDomainNumatuneNodeSpecified(virDomainNumaPtr numatune,
+                                     int cellid);
+ 
+-int virDomainNumaDefCPUParseXML(virDomainNumaPtr def, xmlXPathContextPtr ctxt);
+-int virDomainNumaDefCPUFormatXML(virBufferPtr buf, virDomainNumaPtr def);
++int virDomainNumaDefParseXML(virDomainNumaPtr def, xmlXPathContextPtr ctxt);
++int virDomainNumaDefFormatXML(virBufferPtr buf, virDomainNumaPtr def);
+ 
+ unsigned int virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa);
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-numa_conf-Make-virDomainNumaSetNodeCpumask-return-void.patch b/SOURCES/libvirt-numa_conf-Make-virDomainNumaSetNodeCpumask-return-void.patch
new file mode 100644
index 0000000..f9c60df
--- /dev/null
+++ b/SOURCES/libvirt-numa_conf-Make-virDomainNumaSetNodeCpumask-return-void.patch
@@ -0,0 +1,87 @@
+From a1af99a1129058f2aa312e3c9d125f5bc7693912 Mon Sep 17 00:00:00 2001
+Message-Id: <a1af99a1129058f2aa312e3c9d125f5bc7693912@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 7 Oct 2020 18:45:37 +0200
+Subject: [PATCH] numa_conf: Make virDomainNumaSetNodeCpumask() return void
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There is only one caller of virDomainNumaSetNodeCpumask() which
+checks for the return value but because the function will return
+NULL iff the @cpumask was NULL in the first place. But in that
+place @cpumask can't be NULL because it was just allocated by
+virBitmapParse().
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 1050c6beb1f2238cd847d93eab17d658720b08e1)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <8564849f4fc4aaca69eec3d2b7e59d03234ea39f.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/numa_conf.c | 4 +---
+ src/conf/numa_conf.h | 6 +++---
+ src/libxl/xen_xl.c   | 4 ++--
+ 3 files changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c
+index 38fcf9d9aa..c9cc8ac22e 100644
+--- a/src/conf/numa_conf.c
++++ b/src/conf/numa_conf.c
+@@ -1318,14 +1318,12 @@ virDomainNumaGetNodeCpumask(virDomainNumaPtr numa,
+ }
+ 
+ 
+-virBitmapPtr
++void
+ virDomainNumaSetNodeCpumask(virDomainNumaPtr numa,
+                             size_t node,
+                             virBitmapPtr cpumask)
+ {
+     numa->mem_nodes[node].cpumask = cpumask;
+-
+-    return numa->mem_nodes[node].cpumask;
+ }
+ 
+ 
+diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h
+index ce865cbfbb..6808439a7c 100644
+--- a/src/conf/numa_conf.h
++++ b/src/conf/numa_conf.h
+@@ -156,9 +156,9 @@ size_t virDomainNumaSetNodeDistanceCount(virDomainNumaPtr numa,
+                                          size_t ndistances)
+     ATTRIBUTE_NONNULL(1);
+ 
+-virBitmapPtr virDomainNumaSetNodeCpumask(virDomainNumaPtr numa,
+-                                         size_t node,
+-                                         virBitmapPtr cpumask)
++void  virDomainNumaSetNodeCpumask(virDomainNumaPtr numa,
++                                  size_t node,
++                                  virBitmapPtr cpumask)
+     ATTRIBUTE_NONNULL(1);
+ 
+ /*
+diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c
+index 91b1825399..edea30a86a 100644
+--- a/src/libxl/xen_xl.c
++++ b/src/libxl/xen_xl.c
+@@ -508,10 +508,10 @@ xenParseXLVnuma(virConfPtr conf,
+                             goto cleanup;
+                         }
+ 
+-                        if ((virBitmapParse(vtoken, &cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0) ||
+-                            (virDomainNumaSetNodeCpumask(numa, vnodeCnt, cpumask) == NULL))
++                        if (virBitmapParse(vtoken, &cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0)
+                             goto cleanup;
+ 
++                        virDomainNumaSetNodeCpumask(numa, vnodeCnt, cpumask);
+                         vcpus += virBitmapCountBits(cpumask);
+ 
+                     } else if (STRPREFIX(str, "vdistances")) {
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-numa_conf-Properly-check-for-caches-in-virDomainNumaDefValidate.patch b/SOURCES/libvirt-numa_conf-Properly-check-for-caches-in-virDomainNumaDefValidate.patch
new file mode 100644
index 0000000..525beef
--- /dev/null
+++ b/SOURCES/libvirt-numa_conf-Properly-check-for-caches-in-virDomainNumaDefValidate.patch
@@ -0,0 +1,91 @@
+From 8521a431d3da3cc360eb8102eda1c0d649f1ecc3 Mon Sep 17 00:00:00 2001
+Message-Id: <8521a431d3da3cc360eb8102eda1c0d649f1ecc3@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 7 Oct 2020 18:45:45 +0200
+Subject: [PATCH] numa_conf: Properly check for caches in
+ virDomainNumaDefValidate()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When adding support for HMAT, in f0611fe8830 I've introduced a
+check which aims to validate /domain/cpu/numa/interconnects. As a
+part of that, there is a loop which checks whether all <latency/>
+with @cache attribute refer to an existing cache level. For
+instance:
+
+  <cpu mode='host-model' check='partial'>
+    <numa>
+      <cell id='0' cpus='0-5' memory='512000' unit='KiB' discard='yes'>
+        <cache level='1' associativity='direct' policy='writeback'>
+          <size value='8' unit='KiB'/>
+          <line value='5' unit='B'/>
+        </cache>
+      </cell>
+      <interconnects>
+        <latency initiator='0' target='0' cache='1' type='access' value='5'/>
+        <bandwidth initiator='0' target='0' type='access' value='204800' unit='KiB'/>
+      </interconnects>
+    </numa>
+  </cpu>
+
+This XML defines that accessing L1 cache of node #0 from node #0
+has latency of 5ns.
+
+However, the loop was not written properly. Well, the check in
+it, as it was always checking for the first cache in the target
+node and not the rest. Therefore, the following example errors
+out:
+
+  <cpu mode='host-model' check='partial'>
+    <numa>
+      <cell id='0' cpus='0-5' memory='512000' unit='KiB' discard='yes'>
+        <cache level='3' associativity='direct' policy='writeback'>
+          <size value='10' unit='KiB'/>
+          <line value='8' unit='B'/>
+        </cache>
+        <cache level='1' associativity='direct' policy='writeback'>
+          <size value='8' unit='KiB'/>
+          <line value='5' unit='B'/>
+        </cache>
+      </cell>
+      <interconnects>
+        <latency initiator='0' target='0' cache='1' type='access' value='5'/>
+        <bandwidth initiator='0' target='0' type='access' value='204800' unit='KiB'/>
+      </interconnects>
+    </numa>
+  </cpu>
+
+This errors out even though it is a valid configuration. The L1
+cache under node #0 is still present.
+
+Fixes: f0611fe8830
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Laine Stump <laine@redhat.com>
+(cherry picked from commit e41ac71fca309b50e2c8e6ec142d8fe1280ca2ad)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <4bb47f9e97ca097cee1259449da4739b55753751.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/numa_conf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c
+index 5a92eb35cc..a20398714e 100644
+--- a/src/conf/numa_conf.c
++++ b/src/conf/numa_conf.c
+@@ -1423,7 +1423,7 @@ virDomainNumaDefValidate(const virDomainNuma *def)
+ 
+         if (l->cache > 0) {
+             for (j = 0; j < def->mem_nodes[l->target].ncaches; j++) {
+-                const virDomainNumaCache *cache = def->mem_nodes[l->target].caches;
++                const virDomainNumaCache *cache = &def->mem_nodes[l->target].caches[j];
+ 
+                 if (l->cache == cache->level)
+                     break;
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-qemu-Add-virtio-related-options-to-vsock.patch b/SOURCES/libvirt-qemu-Add-virtio-related-options-to-vsock.patch
index a0a2f4d..4b1eab9 100644
--- a/SOURCES/libvirt-qemu-Add-virtio-related-options-to-vsock.patch
+++ b/SOURCES/libvirt-qemu-Add-virtio-related-options-to-vsock.patch
@@ -1,7 +1,7 @@
-From 1b084c7ff54f1bb36c9e0dee3e1c86a250f3d6af Mon Sep 17 00:00:00 2001
-Message-Id: <1b084c7ff54f1bb36c9e0dee3e1c86a250f3d6af@dist-git>
+From 362d106d8897a3982f5eaed0c4bc0194d6f9ef28 Mon Sep 17 00:00:00 2001
+Message-Id: <362d106d8897a3982f5eaed0c4bc0194d6f9ef28@dist-git>
 From: Boris Fiuczynski <fiuczy@linux.ibm.com>
-Date: Tue, 23 Mar 2021 10:25:46 +0100
+Date: Fri, 26 Feb 2021 06:43:35 -0500
 Subject: [PATCH] qemu: Add virtio related options to vsock
 
 Add virtio related options iommu, ats and packed as driver element attributes
@@ -17,7 +17,7 @@ Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
 Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
 (cherry picked from commit bd112c9e0f7523b90bf1362cf60deea7db05a32b)
 
-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1941820
+Resolves: https://bugzilla.redhat.com/1931548
 
 Note: since the virtio option packed is not yet available in the code
 version it will also not be available with this backported patch.
@@ -31,9 +31,8 @@ Conflicts: docs/formatdomain.rst:
     src/qemu/qemu_validate.c:
     does not exist downstream. can be neglected
 
-Signed-off-by: Thomas Huth <thuth@redhat.com>
-Message-Id: <20210323092546.405902-2-thuth@redhat.com>
-Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <20210226114335.100390-2-bfiuczyn@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
 ---
  docs/formatdomain.html.in                     |  5 ++-
  docs/schemas/domaincommon.rng                 |  5 +++
@@ -51,10 +50,10 @@ Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
  create mode 120000 tests/qemuxml2xmloutdata/vhost-vsock-ccw-iommu.s390x-latest.xml
 
 diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
-index 76799f5ffc..c4e4efcde2 100644
+index bec753e37f..127dd13cc0 100644
 --- a/docs/formatdomain.html.in
 +++ b/docs/formatdomain.html.in
-@@ -9131,7 +9131,10 @@ qemu-kvm -net nic,model=? /dev/null
+@@ -9240,7 +9240,10 @@ qemu-kvm -net nic,model=? /dev/null
      element specifies the CID assigned to the guest. If the attribute
      <code>auto</code> is set to <code>yes</code>, libvirt
      will assign a free CID automatically on domain startup.
@@ -83,7 +82,7 @@ index 9fda5f17e0..4a42cb9b40 100644
      </element>
    </define>
 diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
-index 60962ee7c1..4a4cff434b 100644
+index c5a0442c6f..166c3e48d2 100644
 --- a/src/conf/domain_conf.c
 +++ b/src/conf/domain_conf.c
 @@ -2392,6 +2392,7 @@ virDomainVsockDefFree(virDomainVsockDefPtr vsock)
@@ -121,7 +120,7 @@ index 60962ee7c1..4a4cff434b 100644
      return 0;
  }
  
-@@ -16721,6 +16735,11 @@ virDomainVsockDefParseXML(virDomainXMLOptionPtr xmlopt,
+@@ -16649,6 +16663,11 @@ virDomainVsockDefParseXML(virDomainXMLOptionPtr xmlopt,
      if (virDomainDeviceInfoParseXML(xmlopt, node, &vsock->info, flags) < 0)
          return NULL;
  
@@ -133,7 +132,7 @@ index 60962ee7c1..4a4cff434b 100644
      return g_steal_pointer(&vsock);
  }
  
-@@ -23401,6 +23420,10 @@ virDomainVsockDefCheckABIStability(virDomainVsockDefPtr src,
+@@ -23350,6 +23369,10 @@ virDomainVsockDefCheckABIStability(virDomainVsockDefPtr src,
          return false;
      }
  
@@ -144,7 +143,7 @@ index 60962ee7c1..4a4cff434b 100644
      if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info))
          return false;
  
-@@ -28410,6 +28433,7 @@ virDomainVsockDefFormat(virBufferPtr buf,
+@@ -28364,6 +28387,7 @@ virDomainVsockDefFormat(virBufferPtr buf,
      g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
      g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
      g_auto(virBuffer) cidAttrBuf = VIR_BUFFER_INITIALIZER;
@@ -152,7 +151,7 @@ index 60962ee7c1..4a4cff434b 100644
  
      if (vsock->model) {
          virBufferAsprintf(&attrBuf, " model='%s'",
-@@ -28427,6 +28451,9 @@ virDomainVsockDefFormat(virBufferPtr buf,
+@@ -28381,6 +28405,9 @@ virDomainVsockDefFormat(virBufferPtr buf,
      if (virDomainDeviceInfoFormat(&childBuf, &vsock->info, 0) < 0)
          return -1;
  
@@ -175,10 +174,10 @@ index 118077edaa..3aed1fb22a 100644
  
  struct _virDomainVirtioOptions {
 diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
-index ed5f60e82e..11e59a67d2 100644
+index 67d7334b0f..998c3c90f8 100644
 --- a/src/qemu/qemu_command.c
 +++ b/src/qemu/qemu_command.c
-@@ -9799,6 +9799,10 @@ qemuBuildVsockDevStr(virDomainDefPtr def,
+@@ -9965,6 +9965,10 @@ qemuBuildVsockDevStr(virDomainDefPtr def,
      virBufferAsprintf(&buf, ",id=%s", vsock->info.alias);
      virBufferAsprintf(&buf, ",guest-cid=%u", vsock->guest_cid);
      virBufferAsprintf(&buf, ",vhostfd=%s%u", fdprefix, priv->vhostfd);
@@ -276,10 +275,10 @@ index 0000000000..dbfe082a6f
 +  </devices>
 +</domain>
 diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
-index ff92af606d..66df797ef2 100644
+index 629f5ac100..a22e3ba157 100644
 --- a/tests/qemuxml2argvtest.c
 +++ b/tests/qemuxml2argvtest.c
-@@ -3054,6 +3054,7 @@ mymain(void)
+@@ -3056,6 +3056,7 @@ mymain(void)
      DO_TEST_CAPS_LATEST("vhost-vsock-auto");
      DO_TEST_CAPS_ARCH_LATEST("vhost-vsock-ccw", "s390x");
      DO_TEST_CAPS_ARCH_LATEST("vhost-vsock-ccw-auto", "s390x");
@@ -296,10 +295,10 @@ index 0000000000..78971a8ef9
 +../qemuxml2argvdata/vhost-vsock-ccw-iommu.xml
 \ No newline at end of file
 diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
-index c8218e423e..0e0097da1b 100644
+index 60efcac6c8..461b5bc68f 100644
 --- a/tests/qemuxml2xmltest.c
 +++ b/tests/qemuxml2xmltest.c
-@@ -1429,6 +1429,8 @@ mymain(void)
+@@ -1433,6 +1433,8 @@ mymain(void)
              QEMU_CAPS_CCW);
      DO_TEST("vhost-vsock-ccw-auto", QEMU_CAPS_DEVICE_VHOST_VSOCK,
              QEMU_CAPS_CCW);
@@ -309,5 +308,5 @@ index c8218e423e..0e0097da1b 100644
      DO_TEST_CAPS_LATEST("vhost-user-fs-fd-memory");
      DO_TEST_CAPS_LATEST("vhost-user-fs-hugepages");
 -- 
-2.31.0
+2.30.0
 
diff --git a/SOURCES/libvirt-qemu-Build-HMAT-command-line.patch b/SOURCES/libvirt-qemu-Build-HMAT-command-line.patch
new file mode 100644
index 0000000..d65e257
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Build-HMAT-command-line.patch
@@ -0,0 +1,388 @@
+From fe08906feb3ab006c4013957895cfb4fa69b7396 Mon Sep 17 00:00:00 2001
+Message-Id: <fe08906feb3ab006c4013957895cfb4fa69b7396@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 7 Oct 2020 18:45:43 +0200
+Subject: [PATCH] qemu: Build HMAT command line
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1786303
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit aeecbc87b7317e88a8ef8c82b29bcacd1005c8c2)
+
+Apart from conflicts below, I had to remove '-cpu qemu64' from
+tests/qemuxml2argvdata/numatune-hmat.x86_64-latest.args to make
+qemuxml2argvtest happy. This is because
+3b8feb4793cef66f5dbfb9bdabe4d40834f1e90e isn't backported.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Conflicts:
+- src/qemu/qemu_command.c: Context
+- src/qemu/qemu_validate.c: The file doesn't exist in downstream.
+I've made the change to validator that lives in qemu_domain.c.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <0e8dfded8022b564ec7d0563cd745a0d3ffc815f.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/conf/numa_conf.c                          |   7 +
+ src/qemu/qemu_command.c                       | 171 ++++++++++++++++++
+ src/qemu/qemu_domain.c                        |   7 +
+ .../numatune-hmat.x86_64-latest.args          |  52 ++++++
+ tests/qemuxml2argvtest.c                      |   1 +
+ tests/qemuxml2xmltest.c                       |   2 +-
+ 6 files changed, 239 insertions(+), 1 deletion(-)
+ create mode 100644 tests/qemuxml2argvdata/numatune-hmat.x86_64-latest.args
+
+diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c
+index 277a695d84..5a92eb35cc 100644
+--- a/src/conf/numa_conf.c
++++ b/src/conf/numa_conf.c
+@@ -1875,6 +1875,13 @@ virDomainNumaGetNodeInitiator(const virDomainNuma *numa,
+     if (!numa || node >= numa->nmem_nodes)
+         return -1;
+ 
++    /* A NUMA node which has at least one vCPU is initiator to itself by
++     * definition. */
++    if (numa->mem_nodes[node].cpumask)
++        return node;
++
++    /* For the rest, "NUMA node that has best performance (the lowest
++     * latency or largest bandwidth) to this NUMA node." */
+     for (i = 0; i < numa->ninterconnects; i++) {
+         const virDomainNumaInterconnect *l = &numa->interconnects[i];
+ 
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index ac63d18a42..959207bfea 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -7172,6 +7172,9 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
+             virBufferAsprintf(&buf, ",pflash1=%s", priv->pflash1->nodeformat);
+     }
+ 
++    if (virDomainNumaHasHMAT(def->numa))
++        virBufferAddLit(&buf, ",hmat=on");
++
+     virCommandAddArgBuffer(cmd, &buf);
+ 
+     return 0;
+@@ -7355,6 +7358,134 @@ qemuBuildIOThreadCommandLine(virCommandPtr cmd,
+ }
+ 
+ 
++static int
++qemuBuilNumaCellCache(virCommandPtr cmd,
++                      const virDomainDef *def,
++                      size_t cell)
++{
++    size_t ncaches = virDomainNumaGetNodeCacheCount(def->numa, cell);
++    size_t i;
++
++    if (ncaches == 0)
++        return 0;
++
++    for (i = 0; i < ncaches; i++) {
++        g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
++        unsigned int level;
++        unsigned int size;
++        unsigned int line;
++        virDomainCacheAssociativity associativity;
++        virDomainCachePolicy policy;
++
++        if (virDomainNumaGetNodeCache(def->numa, cell, i,
++                                      &level, &size, &line,
++                                      &associativity, &policy) < 0) {
++            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
++                           _("Unable to format NUMA node cache"));
++            return -1;
++        }
++
++        virBufferAsprintf(&buf,
++                          "hmat-cache,node-id=%zu,size=%uK,level=%u",
++                          cell, size, level);
++
++        switch (associativity) {
++        case VIR_DOMAIN_CACHE_ASSOCIATIVITY_NONE:
++            virBufferAddLit(&buf, ",associativity=none");
++            break;
++        case VIR_DOMAIN_CACHE_ASSOCIATIVITY_DIRECT:
++            virBufferAddLit(&buf, ",associativity=direct");
++            break;
++        case VIR_DOMAIN_CACHE_ASSOCIATIVITY_FULL:
++            virBufferAddLit(&buf, ",associativity=complex");
++            break;
++        case VIR_DOMAIN_CACHE_ASSOCIATIVITY_LAST:
++            break;
++        }
++
++        switch (policy) {
++        case VIR_DOMAIN_CACHE_POLICY_NONE:
++            virBufferAddLit(&buf, ",policy=none");
++            break;
++        case VIR_DOMAIN_CACHE_POLICY_WRITEBACK:
++            virBufferAddLit(&buf, ",policy=write-back");
++            break;
++        case VIR_DOMAIN_CACHE_POLICY_WRITETHROUGH:
++            virBufferAddLit(&buf, ",policy=write-through");
++            break;
++        case VIR_DOMAIN_CACHE_POLICY_LAST:
++            break;
++        }
++
++        if (line > 0)
++            virBufferAsprintf(&buf, ",line=%u", line);
++
++        virCommandAddArg(cmd, "-numa");
++        virCommandAddArgBuffer(cmd, &buf);
++    }
++
++    return 0;
++}
++
++
++VIR_ENUM_DECL(qemuDomainMemoryHierarchy);
++VIR_ENUM_IMPL(qemuDomainMemoryHierarchy,
++              4, /* Maximum level of cache */
++              "memory", /* Special case, whole memory not specific cache */
++              "first-level",
++              "second-level",
++              "third-level");
++
++static int
++qemuBuildNumaHMATCommandLine(virCommandPtr cmd,
++                             const virDomainDef *def)
++{
++    size_t nlatencies;
++    size_t i;
++
++    if (!def->numa)
++        return 0;
++
++    nlatencies = virDomainNumaGetInterconnectsCount(def->numa);
++    for (i = 0; i < nlatencies; i++) {
++        g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
++        virDomainNumaInterconnectType type;
++        unsigned int initiator;
++        unsigned int target;
++        unsigned int cache;
++        virDomainMemoryLatency accessType;
++        unsigned long value;
++        const char *hierarchyStr;
++        const char *accessStr;
++
++        if (virDomainNumaGetInterconnect(def->numa, i,
++                                         &type, &initiator, &target,
++                                         &cache, &accessType, &value) < 0)
++            return -1;
++
++        hierarchyStr = qemuDomainMemoryHierarchyTypeToString(cache);
++        accessStr = virDomainMemoryLatencyTypeToString(accessType);
++        virBufferAsprintf(&buf,
++                          "hmat-lb,initiator=%u,target=%u,hierarchy=%s,data-type=%s-",
++                          initiator, target, hierarchyStr, accessStr);
++
++        switch (type) {
++        case VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_LATENCY:
++            virBufferAsprintf(&buf, "latency,latency=%lu", value);
++            break;
++        case VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_BANDWIDTH:
++            virBufferAsprintf(&buf, "bandwidth,bandwidth=%luK", value);
++            break;
++        }
++
++        virCommandAddArg(cmd, "-numa");
++        virCommandAddArgBuffer(cmd, &buf);
++    }
++
++    return 0;
++}
++
++
+ static int
+ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg,
+                          virDomainDefPtr def,
+@@ -7367,13 +7498,20 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg,
+     char *next = NULL;
+     virBufferPtr nodeBackends = NULL;
+     bool needBackend = false;
++    bool hmat = false;
+     int rc;
+     int ret = -1;
+     size_t ncells = virDomainNumaGetNodeCount(def->numa);
++    ssize_t masterInitiator = -1;
+ 
+     if (!virDomainNumatuneNodesetIsAvailable(def->numa, priv->autoNodeset))
+         goto cleanup;
+ 
++    if (virDomainNumaHasHMAT(def->numa)) {
++        needBackend = true;
++        hmat = true;
++    }
++
+     if (VIR_ALLOC_N(nodeBackends, ncells) < 0)
+         goto cleanup;
+ 
+@@ -7397,8 +7535,22 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg,
+         qemuBuildMemPathStr(cfg, def, cmd, priv) < 0)
+         goto cleanup;
+ 
++    for (i = 0; i < ncells; i++) {
++        if (virDomainNumaGetNodeCpumask(def->numa, i)) {
++            masterInitiator = i;
++            break;
++        }
++    }
++
++    if (masterInitiator) {
++        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                       _("At least one NUMA node has to have CPUs"));
++        goto cleanup;
++    }
++
+     for (i = 0; i < ncells; i++) {
+         virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(def->numa, i);
++        ssize_t initiator = virDomainNumaGetNodeInitiator(def->numa, i);
+ 
+         if (needBackend) {
+             virCommandAddArg(cmd, "-object");
+@@ -7423,6 +7575,13 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg,
+             }
+         }
+ 
++        if (hmat) {
++            if (initiator < 0)
++                initiator = masterInitiator;
++
++            virBufferAsprintf(&buf, ",initiator=%zd", initiator);
++        }
++
+         if (needBackend)
+             virBufferAsprintf(&buf, ",memdev=ram-node%zu", i);
+         else
+@@ -7448,6 +7607,18 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg,
+         }
+     }
+ 
++    if (hmat) {
++        if (qemuBuildNumaHMATCommandLine(cmd, def) < 0)
++            goto cleanup;
++
++        /* This can't be moved into any of the loops above,
++         * because hmat-cache can be specified only after hmat-lb. */
++        for (i = 0; i < ncells; i++) {
++            if (qemuBuilNumaCellCache(cmd, def, i) < 0)
++                goto cleanup;
++        }
++    }
++
+     ret = 0;
+ 
+  cleanup:
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index be25790f12..e51e176a80 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -5904,6 +5904,13 @@ qemuDomainDefValidate(const virDomainDef *def,
+         }
+     }
+ 
++    if (virDomainNumaHasHMAT(def->numa) &&
++        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA_HMAT)) {
++        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
++                       _("HMAT is not supported with this QEMU"));
++        return -1;
++    }
++
+     if (def->genidRequested &&
+         !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMGENID)) {
+         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+diff --git a/tests/qemuxml2argvdata/numatune-hmat.x86_64-latest.args b/tests/qemuxml2argvdata/numatune-hmat.x86_64-latest.args
+new file mode 100644
+index 0000000000..413d247a4d
+--- /dev/null
++++ b/tests/qemuxml2argvdata/numatune-hmat.x86_64-latest.args
+@@ -0,0 +1,52 @@
++LC_ALL=C \
++PATH=/bin \
++HOME=/tmp/lib/domain--1-QEMUGuest \
++USER=test \
++LOGNAME=test \
++XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest/.local/share \
++XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest/.cache \
++XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest/.config \
++QEMU_AUDIO_DRV=none \
++/usr/bin/qemu-system-x86_64 \
++-name guest=QEMUGuest,debug-threads=on \
++-S \
++-object secret,id=masterKey0,format=raw,\
++file=/tmp/lib/domain--1-QEMUGuest/master-key.aes \
++-machine pc,accel=tcg,usb=off,dump-guest-core=off,hmat=on \
++-m 12288 \
++-overcommit mem-lock=off \
++-smp 12,sockets=12,cores=1,threads=1 \
++-object memory-backend-ram,id=ram-node0,size=2147483648 \
++-numa node,nodeid=0,cpus=0-3,initiator=0,memdev=ram-node0 \
++-object memory-backend-ram,id=ram-node1,size=2147483648 \
++-numa node,nodeid=1,cpus=4-7,initiator=1,memdev=ram-node1 \
++-object memory-backend-ram,id=ram-node2,size=2147483648 \
++-numa node,nodeid=2,cpus=8-11,initiator=2,memdev=ram-node2 \
++-object memory-backend-ram,id=ram-node3,size=2147483648 \
++-numa node,nodeid=3,initiator=0,memdev=ram-node3 \
++-object memory-backend-ram,id=ram-node4,size=2147483648 \
++-numa node,nodeid=4,initiator=0,memdev=ram-node4 \
++-object memory-backend-ram,id=ram-node5,size=2147483648 \
++-numa node,nodeid=5,initiator=0,memdev=ram-node5 \
++-numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-latency,\
++latency=5 \
++-numa hmat-lb,initiator=0,target=0,hierarchy=first-level,\
++data-type=access-latency,latency=10 \
++-numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-bandwidth,\
++bandwidth=204800K \
++-numa hmat-cache,node-id=0,size=10K,level=1,associativity=direct,\
++policy=write-back,line=8 \
++-uuid c7a5fdb2-cdaf-9455-926a-d65c16db1809 \
++-display none \
++-no-user-config \
++-nodefaults \
++-chardev socket,id=charmonitor,fd=1729,server,nowait \
++-mon chardev=charmonitor,id=monitor,mode=control \
++-rtc base=utc \
++-no-shutdown \
++-boot strict=on \
++-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
++-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \
++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
++resourcecontrol=deny \
++-msg timestamp=on
+diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
+index 49699e495d..629f5ac100 100644
+--- a/tests/qemuxml2argvtest.c
++++ b/tests/qemuxml2argvtest.c
+@@ -1813,6 +1813,7 @@ mymain(void)
+ 
+     DO_TEST("numatune-distances", QEMU_CAPS_NUMA, QEMU_CAPS_NUMA_DIST);
+     DO_TEST("numatune-no-vcpu", NONE);
++    DO_TEST_CAPS_LATEST("numatune-hmat");
+ 
+     DO_TEST("numatune-auto-nodeset-invalid", NONE);
+     DO_TEST("numatune-auto-prefer", QEMU_CAPS_OBJECT_MEMORY_RAM,
+diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
+index de1d720e1d..f790bbc6f1 100644
+--- a/tests/qemuxml2xmltest.c
++++ b/tests/qemuxml2xmltest.c
+@@ -1106,7 +1106,7 @@ mymain(void)
+     DO_TEST("numatune-memnode-no-memory", QEMU_CAPS_OBJECT_MEMORY_FILE);
+     DO_TEST("numatune-distances", QEMU_CAPS_NUMA, QEMU_CAPS_NUMA_DIST);
+     DO_TEST("numatune-no-vcpu", QEMU_CAPS_NUMA);
+-    DO_TEST("numatune-hmat", NONE);
++    DO_TEST("numatune-hmat", QEMU_CAPS_NUMA_HMAT);
+ 
+     DO_TEST("bios-nvram", NONE);
+     DO_TEST("bios-nvram-os-interleave", NONE);
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-qemu-Fix-domfsinfo-for-non-PCI-device-information-from-guest-agent.patch b/SOURCES/libvirt-qemu-Fix-domfsinfo-for-non-PCI-device-information-from-guest-agent.patch
new file mode 100644
index 0000000..d1f5cda
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Fix-domfsinfo-for-non-PCI-device-information-from-guest-agent.patch
@@ -0,0 +1,70 @@
+From c1605fba8512fc77f3e2e2bdbbca56e14a086893 Mon Sep 17 00:00:00 2001
+Message-Id: <c1605fba8512fc77f3e2e2bdbbca56e14a086893@dist-git>
+From: Thomas Huth <thuth@redhat.com>
+Date: Fri, 2 Oct 2020 12:32:11 +0200
+Subject: [PATCH] qemu: Fix domfsinfo for non-PCI device information from guest
+ agent
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+qemuAgentFSInfoToPublic() currently only sets the devAlias for PCI devices.
+However, the QEMU guest agent could also provide the device name in the
+"dev" field of the response for other devices instead (well, at least after
+fixing another problem in the current QEMU guest agent...). So if creating
+the devAlias from the PCI information failed, let's fall back to the name
+provided by the guest agent. This helps to fix the empty "Target" fields
+that occur when running "virsh domfsinfo" on s390x where CCW devices are
+used for the guest instead of PCI devices.
+
+Also add a proper debug message here in case we completely failed to set the
+device alias, since this problem here was very hard to debug: The only two
+error messages that I've seen were "Unable to get filesystem information"
+and "Unable to encode message payload" - which only indicates that something
+went wrong in the RPC call. No debug message indicated the real problem, so
+I had to learn the hard way why the RPC call failed (it apparently does not
+like devAlias left to be NULL) and where the real problem comes from.
+
+Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
+Signed-off-by: Thomas Huth <thuth@redhat.com>
+(cherry picked from commit f8333b3b0a7fdbc1f18ed501c043ac7618b86a16)
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1858771
+Message-Id: <20201002103211.250169-2-thuth@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/qemu/qemu_driver.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 0f06974a1b..80a4a43e2e 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -21996,14 +21996,17 @@ qemuAgentFSInfoToPublic(qemuAgentFSInfoPtr agent,
+         qemuAgentDiskInfoPtr agentdisk = agent->disks[i];
+         virDomainDiskDefPtr diskDef;
+ 
+-        if (!(diskDef = virDomainDiskByAddress(vmdef,
+-                                               &agentdisk->pci_controller,
+-                                               agentdisk->bus,
+-                                               agentdisk->target,
+-                                               agentdisk->unit)))
+-            continue;
+-
+-        ret->devAlias[i] = g_strdup(diskDef->dst);
++        diskDef = virDomainDiskByAddress(vmdef,
++                                         &agentdisk->pci_controller,
++                                         agentdisk->bus,
++                                         agentdisk->target,
++                                         agentdisk->unit);
++        if (diskDef != NULL)
++            ret->devAlias[i] = g_strdup(diskDef->dst);
++        else if (agentdisk->devnode != NULL)
++            ret->devAlias[i] = g_strdup(agentdisk->devnode);
++        else
++            VIR_DEBUG("Missing devnode name for '%s'.", ret->mountpoint);
+     }
+ 
+     return ret;
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-qemu-Introduce-QEMU_CAPS_NUMA_HMAT-capability.patch b/SOURCES/libvirt-qemu-Introduce-QEMU_CAPS_NUMA_HMAT-capability.patch
new file mode 100644
index 0000000..1354f7c
--- /dev/null
+++ b/SOURCES/libvirt-qemu-Introduce-QEMU_CAPS_NUMA_HMAT-capability.patch
@@ -0,0 +1,97 @@
+From f1de31795f1010016beab3b669db821799e5a6d3 Mon Sep 17 00:00:00 2001
+Message-Id: <f1de31795f1010016beab3b669db821799e5a6d3@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 7 Oct 2020 18:45:42 +0200
+Subject: [PATCH] qemu: Introduce QEMU_CAPS_NUMA_HMAT capability
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This capability tracks whether QEMU is capable of defining HMAT
+ACPI table for the guest.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit c2f15f1b1869c1732e529967d1851582409290fb)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Conflicts:
+- src/qemu/qemu_capabilities.c: The set of capabilities diverged.
+- src/qemu/qemu_capabilities.h: Ditto.
+- tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml: Ditto.
+- tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml: Ditto.
+- tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml: Doesn't exist
+  downstream.
+- tests/qemucapabilitiesdata/caps_5.0.0.riscv64.xml: Ditto.
+- tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml: Ditto.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <bf15c10c27c81f8f2d5a23568e4aebd216756642.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_capabilities.c                      | 2 ++
+ src/qemu/qemu_capabilities.h                      | 1 +
+ tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml | 1 +
+ tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml  | 1 +
+ 4 files changed, 5 insertions(+)
+
+diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
+index 278eaa0009..ce52c51199 100644
+--- a/src/qemu/qemu_capabilities.c
++++ b/src/qemu/qemu_capabilities.c
+@@ -568,6 +568,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
+               "storage.werror",
+               "pcie-root-port.hotplug",
+               "i8042",
++              "numa.hmat",
+     );
+ 
+ 
+@@ -1451,6 +1452,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = {
+     { "human-monitor-command/$savevm-monitor-nodes", QEMU_CAPS_SAVEVM_MONITOR_NODES },
+     { "blockdev-add/arg-type/+nvme", QEMU_CAPS_DRIVE_NVME },
+     { "blockdev-snapshot/$allow-write-only-overlay", QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY },
++    { "set-numa-node/arg-type/+hmat-lb", QEMU_CAPS_NUMA_HMAT },
+ };
+ 
+ typedef struct _virQEMUCapsObjectTypeProps virQEMUCapsObjectTypeProps;
+diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
+index 15ebcb5077..98cac5b9dc 100644
+--- a/src/qemu/qemu_capabilities.h
++++ b/src/qemu/qemu_capabilities.h
+@@ -548,6 +548,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
+     QEMU_CAPS_STORAGE_WERROR, /* virtio-blk,scsi-hd.werror */
+     QEMU_CAPS_PCIE_ROOT_PORT_HOTPLUG, /* pcie-root-port.hotplug */
+     QEMU_CAPS_DEVICE_I8042, /* PS/2 controller */
++    QEMU_CAPS_NUMA_HMAT, /* -numa hmat */
+ 
+     QEMU_CAPS_LAST /* this must always be the last item */
+ } virQEMUCapsFlags;
+diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
+index 140a466910..92da5cbd94 100644
+--- a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
++++ b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml
+@@ -181,6 +181,7 @@
+   <flag name='cpu.kvm-no-adjvtime'/>
+   <flag name='vhost-user-fs'/>
+   <flag name='storage.werror'/>
++  <flag name='numa.hmat'/>
+   <version>4002050</version>
+   <kvmVersion>0</kvmVersion>
+   <microcodeVersion>61700241</microcodeVersion>
+diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml
+index 733e6b1eb4..0b841a49ac 100644
+--- a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml
++++ b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml
+@@ -226,6 +226,7 @@
+   <flag name='storage.werror'/>
+   <flag name='pcie-root-port.hotplug'/>
+   <flag name='i8042'/>
++  <flag name='numa.hmat'/>
+   <version>4002091</version>
+   <kvmVersion>0</kvmVersion>
+   <microcodeVersion>43100241</microcodeVersion>
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-qemu-agent-set-ifname-to-NULL-after-freeing.patch b/SOURCES/libvirt-qemu-agent-set-ifname-to-NULL-after-freeing.patch
new file mode 100644
index 0000000..4eabc76
--- /dev/null
+++ b/SOURCES/libvirt-qemu-agent-set-ifname-to-NULL-after-freeing.patch
@@ -0,0 +1,42 @@
+From 1b7381da7db7092bf774779a610f153532efa5d4 Mon Sep 17 00:00:00 2001
+Message-Id: <1b7381da7db7092bf774779a610f153532efa5d4@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Tue, 29 Sep 2020 14:43:06 +0200
+Subject: [PATCH] qemu: agent: set ifname to NULL after freeing
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+CVE-2020-25637
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
+Fixes: 0977b8aa071de550e1a013d35e2c72615e65d520
+Reviewed-by: Mauro Matteo Cascella <mcascell@redhat.com>
+(cherry picked from commit a63b48c5ecef077bf0f909a85f453a605600cf05)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+
+Conflicts: src/qemu/qemu_agent.c
+    Commit ee247e1d which switched virStringListFree
+    to g_strfreev is missing downstream.
+Message-Id: <01acbf07b5b165b89cc73a127fe7bda666bdf235.1601383236.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_agent.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
+index f13126aeee..968534b594 100644
+--- a/src/qemu/qemu_agent.c
++++ b/src/qemu/qemu_agent.c
+@@ -2192,6 +2192,7 @@ qemuAgentGetInterfaces(qemuAgentPtr mon,
+ 
+         /* Has to be freed for each interface. */
+         virStringListFree(ifname);
++        ifname = NULL;
+ 
+         /* as well as IP address which - moreover -
+          * can be presented multiple times */
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch b/SOURCES/libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch
new file mode 100644
index 0000000..8545d91
--- /dev/null
+++ b/SOURCES/libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch
@@ -0,0 +1,114 @@
+From 9a993a7d566b7acdc548c1f0114b99fe17ba3c12 Mon Sep 17 00:00:00 2001
+Message-Id: <9a993a7d566b7acdc548c1f0114b99fe17ba3c12@dist-git>
+From: Jonathon Jongsma <jjongsma@redhat.com>
+Date: Fri, 4 Dec 2020 15:02:42 -0600
+Subject: [PATCH] qemu: format 'ramfb' attribute for mediated devices
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It's possible to use ramfb as the boot display of an assigned vgpu
+device. This was introduced in 4b95738c, but unfortunately the attribute
+was not formatted into the xml output for such a device. This patch
+fixes that oversight and adds a xml2xml test to verify proper behavior.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1847791
+
+(the expected test results were massaged slightly due to the fact that
+commit 3b8feb4793cef66f5dbfb9bdabe4d40834f1e90e is not present in this
+build).
+
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit c5815b31976f3982d18c7f6c1367ab6e403eb7eb)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1876297
+
+Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
+Message-Id: <20201204210242.822641-2-jjongsma@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/conf/domain_conf.c                        |  3 ++
+ ...stdev-mdev-display-ramfb.x86_64-latest.xml | 41 +++++++++++++++++++
+ tests/qemuxml2xmltest.c                       |  1 +
+ 3 files changed, 45 insertions(+)
+ create mode 100644 tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml
+
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index cd5c15f297..c5a0442c6f 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -27603,6 +27603,9 @@ virDomainHostdevDefFormat(virBufferPtr buf,
+             if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT)
+                 virBufferAsprintf(buf, " display='%s'",
+                                   virTristateSwitchTypeToString(mdevsrc->display));
++            if (mdevsrc->ramfb != VIR_TRISTATE_SWITCH_ABSENT)
++                virBufferAsprintf(buf, " ramfb='%s'",
++                                  virTristateSwitchTypeToString(mdevsrc->ramfb));
+         }
+ 
+     }
+diff --git a/tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml b/tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml
+new file mode 100644
+index 0000000000..90c49842a5
+--- /dev/null
++++ b/tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml
+@@ -0,0 +1,41 @@
++<domain type='qemu'>
++  <name>QEMUGuest2</name>
++  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>219136</memory>
++  <currentMemory unit='KiB'>219136</currentMemory>
++  <vcpu placement='static'>1</vcpu>
++  <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>
++    <emulator>/usr/bin/qemu-system-i386</emulator>
++    <controller type='usb' index='0' model='piix3-uhci'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
++    </controller>
++    <controller type='pci' index='0' model='pci-root'/>
++    <controller type='ide' index='0'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
++    </controller>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <graphics type='vnc' port='-1' autoport='yes'>
++      <listen type='address'/>
++    </graphics>
++    <video>
++      <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
++    </video>
++    <hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci' display='on' ramfb='on'>
++      <source>
++        <address uuid='53764d0e-85a0-42b4-af5c-2046b460b1dc'/>
++      </source>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
++    </hostdev>
++    <memballoon model='none'/>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
+index f790bbc6f1..60efcac6c8 100644
+--- a/tests/qemuxml2xmltest.c
++++ b/tests/qemuxml2xmltest.c
+@@ -524,6 +524,7 @@ mymain(void)
+             QEMU_CAPS_VFIO_PCI_DISPLAY,
+             QEMU_CAPS_DEVICE_VFIO_PCI,
+             QEMU_CAPS_VNC);
++    DO_TEST_CAPS_LATEST("hostdev-mdev-display-ramfb");
+     DO_TEST("pci-rom", NONE);
+     DO_TEST("pci-rom-disabled", NONE);
+     DO_TEST("pci-rom-disabled-invalid", NONE);
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-qemu-move-cgroup-cpu-period-and-quota-defines-to-vircgroup.h.patch b/SOURCES/libvirt-qemu-move-cgroup-cpu-period-and-quota-defines-to-vircgroup.h.patch
new file mode 100644
index 0000000..2ee6d62
--- /dev/null
+++ b/SOURCES/libvirt-qemu-move-cgroup-cpu-period-and-quota-defines-to-vircgroup.h.patch
@@ -0,0 +1,130 @@
+From 7a964b43185f4d818eec0c39197bde17371f4c2b Mon Sep 17 00:00:00 2001
+Message-Id: <7a964b43185f4d818eec0c39197bde17371f4c2b@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Thu, 21 Jan 2021 10:24:03 -0300
+Subject: [PATCH] qemu: move cgroup cpu period and quota defines to vircgroup.h
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit a818e3f6f02ffc9c1c9ea6e8131c307213fa18ec)
+
+Conflicts:  src/qemu/qemu_driver.c
+    Context due to lots of changes upstream in the file.
+
+https://bugzilla.redhat.com/1915733
+
+Signed-off-by: Daniel Henrique Barboza <dbarboza@redhat.com>
+Message-Id: <20210121132406.337681-2-dbarboza@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+---
+ src/qemu/qemu_driver.c | 21 ++++++++-------------
+ src/util/vircgroup.h   |  5 +++++
+ 2 files changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 80a4a43e2e..a1103a96dd 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -122,11 +122,6 @@ VIR_LOG_INIT("qemu.qemu_driver");
+ 
+ #define QEMU_NB_NUMA_PARAM 2
+ 
+-#define QEMU_SCHED_MIN_PERIOD              1000LL
+-#define QEMU_SCHED_MAX_PERIOD           1000000LL
+-#define QEMU_SCHED_MIN_QUOTA               1000LL
+-#define QEMU_SCHED_MAX_QUOTA  18446744073709551LL
+-
+ #define QEMU_GUEST_VCPU_MAX_ID 4096
+ 
+ #define QEMU_NB_BLKIO_PARAM  6
+@@ -10655,7 +10650,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom,
+ 
+         } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD)) {
+             SCHED_RANGE_CHECK(value_ul, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD,
+-                              QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD);
++                              VIR_CGROUP_CPU_PERIOD_MIN, VIR_CGROUP_CPU_PERIOD_MAX);
+ 
+             if (def && value_ul) {
+                 if ((rc = qemuSetVcpusBWLive(vm, priv->cgroup, value_ul, 0)))
+@@ -10675,7 +10670,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom,
+ 
+         } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA)) {
+             SCHED_RANGE_CHECK(value_l, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA,
+-                              QEMU_SCHED_MIN_QUOTA, QEMU_SCHED_MAX_QUOTA);
++                              VIR_CGROUP_CPU_QUOTA_MIN, VIR_CGROUP_CPU_QUOTA_MAX);
+ 
+             if (def && value_l) {
+                 if ((rc = qemuSetVcpusBWLive(vm, priv->cgroup, 0, value_l)))
+@@ -10695,7 +10690,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom,
+ 
+         } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD)) {
+             SCHED_RANGE_CHECK(value_ul, VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD,
+-                              QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD);
++                              VIR_CGROUP_CPU_PERIOD_MIN, VIR_CGROUP_CPU_PERIOD_MAX);
+ 
+             if (def && value_ul) {
+                 if ((rc = qemuSetGlobalBWLive(priv->cgroup, value_ul, 0)))
+@@ -10715,7 +10710,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom,
+ 
+         } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA)) {
+             SCHED_RANGE_CHECK(value_l, VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA,
+-                              QEMU_SCHED_MIN_QUOTA, QEMU_SCHED_MAX_QUOTA);
++                              VIR_CGROUP_CPU_QUOTA_MIN, VIR_CGROUP_CPU_QUOTA_MAX);
+ 
+             if (def && value_l) {
+                 if ((rc = qemuSetGlobalBWLive(priv->cgroup, 0, value_l)))
+@@ -10735,7 +10730,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom,
+ 
+         } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD)) {
+             SCHED_RANGE_CHECK(value_ul, VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD,
+-                              QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD);
++                              VIR_CGROUP_CPU_PERIOD_MIN, VIR_CGROUP_CPU_PERIOD_MAX);
+ 
+             if (def && value_ul) {
+                 if ((rc = qemuSetEmulatorBandwidthLive(priv->cgroup,
+@@ -10756,7 +10751,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom,
+ 
+         } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_EMULATOR_QUOTA)) {
+             SCHED_RANGE_CHECK(value_l, VIR_DOMAIN_SCHEDULER_EMULATOR_QUOTA,
+-                              QEMU_SCHED_MIN_QUOTA, QEMU_SCHED_MAX_QUOTA);
++                              VIR_CGROUP_CPU_QUOTA_MIN, VIR_CGROUP_CPU_QUOTA_MAX);
+ 
+             if (def && value_l) {
+                 if ((rc = qemuSetEmulatorBandwidthLive(priv->cgroup,
+@@ -10777,7 +10772,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom,
+ 
+         } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD)) {
+             SCHED_RANGE_CHECK(value_ul, VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD,
+-                              QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD);
++                              VIR_CGROUP_CPU_PERIOD_MIN, VIR_CGROUP_CPU_PERIOD_MAX);
+ 
+             if (def && value_ul) {
+                 if ((rc = qemuSetIOThreadsBWLive(vm, priv->cgroup, value_ul, 0)))
+@@ -10797,7 +10792,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom,
+ 
+         } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA)) {
+             SCHED_RANGE_CHECK(value_l, VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA,
+-                              QEMU_SCHED_MIN_QUOTA, QEMU_SCHED_MAX_QUOTA);
++                              VIR_CGROUP_CPU_QUOTA_MIN, VIR_CGROUP_CPU_QUOTA_MAX);
+ 
+             if (def && value_l) {
+                 if ((rc = qemuSetIOThreadsBWLive(vm, priv->cgroup, 0, value_l)))
+diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
+index 3eefe78787..83fa74840f 100644
+--- a/src/util/vircgroup.h
++++ b/src/util/vircgroup.h
+@@ -243,6 +243,11 @@ virCgroupGetDomainTotalCpuStats(virCgroupPtr group,
+ int virCgroupSetCpuShares(virCgroupPtr group, unsigned long long shares);
+ int virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares);
+ 
++#define VIR_CGROUP_CPU_PERIOD_MIN 1000LL
++#define VIR_CGROUP_CPU_PERIOD_MAX 1000000LL
++#define VIR_CGROUP_CPU_QUOTA_MIN 1000LL
++#define VIR_CGROUP_CPU_QUOTA_MAX 18446744073709551LL
++
+ int virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period);
+ int virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period);
+ 
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-qemu-substitute-missing-model-name-for-host-passthrough.patch b/SOURCES/libvirt-qemu-substitute-missing-model-name-for-host-passthrough.patch
new file mode 100644
index 0000000..2bb13d9
--- /dev/null
+++ b/SOURCES/libvirt-qemu-substitute-missing-model-name-for-host-passthrough.patch
@@ -0,0 +1,58 @@
+From 961deedc28962b55c37430f974016aced31e1120 Mon Sep 17 00:00:00 2001
+Message-Id: <961deedc28962b55c37430f974016aced31e1120@dist-git>
+From: Collin Walling <walling@linux.ibm.com>
+Date: Fri, 2 Oct 2020 10:13:11 +0200
+Subject: [PATCH] qemu: substitute missing model name for host-passthrough
+
+Before:
+  $ uname -m
+  s390x
+  $ cat passthrough-cpu.xml
+  <cpu check="none" mode="host-passthrough" />
+  $ virsh hypervisor-cpu-compare passthrough-cpu.xml
+  error: Failed to compare hypervisor CPU with passthrough-cpu.xml
+  error: internal error: unable to execute QEMU command 'query-cpu-model-comp
+  arison': Invalid parameter type for 'modelb.name', expected: string
+
+After:
+  $ virsh hypervisor-cpu-compare passthrough-cpu.xml
+  CPU described in passthrough-cpu.xml is identical to the CPU provided by hy
+  pervisor on the host
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Signed-off-by: Collin Walling <walling@linux.ibm.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+(cherry picked from commit 9c6996124f4ef1635fbfe47090dadaf5a12b42e9)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1850680
+
+Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
+Message-Id: <20201002081311.449901-2-twiederh@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/qemu/qemu_driver.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index b5df0c63d4..f8a259e020 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -13539,6 +13539,15 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn,
+         if (virCPUDefParseXMLString(xmlCPU, VIR_CPU_TYPE_AUTO, &cpu) < 0)
+             goto cleanup;
+ 
++        if (!cpu->model) {
++            if (cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) {
++                cpu->model = g_strdup("host");
++            } else {
++                virReportError(VIR_ERR_INVALID_ARG, "%s",
++                               _("cpu parameter is missing a model name"));
++                goto cleanup;
++            }
++        }
+         ret = qemuConnectCPUModelComparison(qemuCaps, cfg->libDir,
+                                             cfg->user, cfg->group,
+                                             hvCPU, cpu, failIncompatible);
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-qemuBuildMachineCommandLine-Drop-needless-check.patch b/SOURCES/libvirt-qemuBuildMachineCommandLine-Drop-needless-check.patch
new file mode 100644
index 0000000..a904b27
--- /dev/null
+++ b/SOURCES/libvirt-qemuBuildMachineCommandLine-Drop-needless-check.patch
@@ -0,0 +1,46 @@
+From 4a3d416229ddf600ff985f9a90e3feb669548690 Mon Sep 17 00:00:00 2001
+Message-Id: <4a3d416229ddf600ff985f9a90e3feb669548690@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 7 Oct 2020 18:45:36 +0200
+Subject: [PATCH] qemuBuildMachineCommandLine: Drop needless check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The machine can not be NULL at this point -
+qemuDomainDefPostParse() makes sure it isn't.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit fe43b3a5a5532377f7de40e77ca9ffde5aa2ca7e)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <4a0c05b78ac65e598b919acdb66d24a19fcf6251.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_command.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index 8c4f7a015f..1a573c2817 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -6977,13 +6977,6 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
+     g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+     size_t i;
+ 
+-    /* This should *never* be NULL, since we always provide
+-     * a machine in the capabilities data for QEMU. So this
+-     * check is just here as a safety in case the unexpected
+-     * happens */
+-    if (!def->os.machine)
+-        return 0;
+-
+     virCommandAddArg(cmd, "-machine");
+     virBufferAdd(&buf, def->os.machine, -1);
+ 
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-qemuBuildNumaCommandLine-Fix-masterInitiator-check.patch b/SOURCES/libvirt-qemuBuildNumaCommandLine-Fix-masterInitiator-check.patch
new file mode 100644
index 0000000..2186773
--- /dev/null
+++ b/SOURCES/libvirt-qemuBuildNumaCommandLine-Fix-masterInitiator-check.patch
@@ -0,0 +1,46 @@
+From a8905f41cd62a0553e703f1b653dd4f6b1acd31f Mon Sep 17 00:00:00 2001
+Message-Id: <a8905f41cd62a0553e703f1b653dd4f6b1acd31f@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 7 Oct 2020 18:45:44 +0200
+Subject: [PATCH] qemuBuildNumaCommandLine: Fix @masterInitiator check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+A few commits ago, in aeecbc87b73, I've implemented command line
+generation for ACPI HMAT. For this, we need to know if at least
+one guest NUMA node has vCPUs. This is tracked in
+@masterInitiator variable, which is initialized to -1, then we
+iterate through guest NUMA nodes and break the loop if we find a
+node with a vCPU. After the loop, if masterInitiator is still
+negative then no NUMA node has a vCPU and we error out. But this
+exact check was missing comparison for negativeness.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit ccf627c110a178afa529818474e555bca62fc165)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <d126e3fe0064d127a1ce6f36c36708e7501e4b5e.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_command.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index 959207bfea..67d7334b0f 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -7542,7 +7542,7 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg,
+         }
+     }
+ 
+-    if (masterInitiator) {
++    if (masterInitiator < 0) {
+         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                        _("At least one NUMA node has to have CPUs"));
+         goto cleanup;
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-qemuFirmwareFillDomain-Fill-NVRAM-template-on-migration-too.patch b/SOURCES/libvirt-qemuFirmwareFillDomain-Fill-NVRAM-template-on-migration-too.patch
new file mode 100644
index 0000000..51fabce
--- /dev/null
+++ b/SOURCES/libvirt-qemuFirmwareFillDomain-Fill-NVRAM-template-on-migration-too.patch
@@ -0,0 +1,69 @@
+From 1824bb0b44b47af95f50afd626776acfba91174d Mon Sep 17 00:00:00 2001
+Message-Id: <1824bb0b44b47af95f50afd626776acfba91174d@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 7 Oct 2020 13:20:04 +0200
+Subject: [PATCH] qemuFirmwareFillDomain: Fill NVRAM template on migration too
+
+In 8e1804f9f66 I've tried to fix the following use case: domain
+is started with path to UEFI only and relies on libvirt to figure
+out corresponding NVRAM template to create a per-domain copy
+from. The fix consisted of having a check tailored exactly for
+this use case and if it's hit then using FW autoselection to
+figure it out. Unfortunately, the NVRAM template is not saved in
+the inactive XML (well, the domain might be transient anyway).
+Then, as a part of that check we see whether the per-domain copy
+doesn't exist already and if it does then no template is looked
+up hence no template will appear in the live XML.
+
+This works, until the domain is migrated. At the destination, the
+per-domain copy will not exist so we need to know the template to
+create the per-domain copy from. But we don't even get to the
+check because we are not starting a fresh new domain and thus the
+qemuFirmwareFillDomain() function quits early.
+
+The solution is to switch order of these two checks. That is
+evaluate the check for the old style before checking flags.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1852910
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Andrea Bolognani <abologna@redhat.com>
+(cherry picked from commit c43622f06e295edcb9cedf33583f0bd18fb04b10)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1880418
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <9b91110a238eba22f4b876e7b15a25d5113ee91e.1602069592.git.mprivozn@redhat.com>
+Reviewed-by: Andrea Bolognani <abologna@redhat.com>
+---
+ src/qemu/qemu_firmware.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
+index 68e2c6b40f..c84d03f0a8 100644
+--- a/src/qemu/qemu_firmware.c
++++ b/src/qemu/qemu_firmware.c
+@@ -1241,9 +1241,6 @@ qemuFirmwareFillDomain(virQEMUDriverPtr driver,
+     size_t i;
+     int ret = -1;
+ 
+-    if (!(flags & VIR_QEMU_PROCESS_START_NEW))
+-        return 0;
+-
+     /* Fill in FW paths if either os.firmware is enabled, or
+      * loader path was provided with no nvram varstore. */
+     if (def->os.firmware == VIR_DOMAIN_OS_DEF_FIRMWARE_NONE) {
+@@ -1259,6 +1256,11 @@ qemuFirmwareFillDomain(virQEMUDriverPtr driver,
+         /* ... then we want to consult JSON FW descriptors first,
+          * but we don't want to fail if we haven't found a match. */
+         needResult = false;
++    } else {
++        /* Domain has FW autoselection enabled => do nothing if
++         * we are not starting it from scratch. */
++        if (!(flags & VIR_QEMU_PROCESS_START_NEW))
++            return 0;
+     }
+ 
+     if ((nfirmwares = qemuFirmwareFetchParsedConfigs(driver->privileged,
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-qemu_command-Rename-qemuBuildNumaArgStr.patch b/SOURCES/libvirt-qemu_command-Rename-qemuBuildNumaArgStr.patch
new file mode 100644
index 0000000..7b61648
--- /dev/null
+++ b/SOURCES/libvirt-qemu_command-Rename-qemuBuildNumaArgStr.patch
@@ -0,0 +1,57 @@
+From 4fd196d6126cb9daeb771522ad23ecba0e9fd5c9 Mon Sep 17 00:00:00 2001
+Message-Id: <4fd196d6126cb9daeb771522ad23ecba0e9fd5c9@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 7 Oct 2020 18:45:35 +0200
+Subject: [PATCH] qemu_command: Rename qemuBuildNumaArgStr()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The function doesn't just build the argument for -numa. Since the
+-numa can be repeated multiple times, it also puts -numa onto the
+cmd line. Also, the rest of the functions has 'Command' infix.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 8ba1792785e17736db866d62b68812a9c7e7ca40)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <f5e22c8cfce2a9636303e916d97ce0501376137f.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/qemu/qemu_command.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
+index ed5f60e82e..8c4f7a015f 100644
+--- a/src/qemu/qemu_command.c
++++ b/src/qemu/qemu_command.c
+@@ -7363,10 +7363,10 @@ qemuBuildIOThreadCommandLine(virCommandPtr cmd,
+ 
+ 
+ static int
+-qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg,
+-                    virDomainDefPtr def,
+-                    virCommandPtr cmd,
+-                    qemuDomainObjPrivatePtr priv)
++qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg,
++                         virDomainDefPtr def,
++                         virCommandPtr cmd,
++                         qemuDomainObjPrivatePtr priv)
+ {
+     size_t i, j;
+     virQEMUCapsPtr qemuCaps = priv->qemuCaps;
+@@ -9930,7 +9930,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
+         return NULL;
+ 
+     if (virDomainNumaGetNodeCount(def->numa) &&
+-        qemuBuildNumaArgStr(cfg, def, cmd, priv) < 0)
++        qemuBuildNumaCommandLine(cfg, def, cmd, priv) < 0)
+         return NULL;
+ 
+     if (qemuBuildMemoryDeviceCommandLine(cmd, cfg, def, priv) < 0)
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-qemuxml2xmltest-Add-numatune-distance-test-case.patch b/SOURCES/libvirt-qemuxml2xmltest-Add-numatune-distance-test-case.patch
new file mode 100644
index 0000000..64b5e6f
--- /dev/null
+++ b/SOURCES/libvirt-qemuxml2xmltest-Add-numatune-distance-test-case.patch
@@ -0,0 +1,145 @@
+From 6047fac5e90c96d2d79b08e0c9d32ee7f0ad52cd Mon Sep 17 00:00:00 2001
+Message-Id: <6047fac5e90c96d2d79b08e0c9d32ee7f0ad52cd@dist-git>
+From: Michal Privoznik <mprivozn@redhat.com>
+Date: Wed, 7 Oct 2020 18:45:32 +0200
+Subject: [PATCH] qemuxml2xmltest: Add "numatune-distance" test case
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This test case checks that expanding NUMA distance works. On
+input we accept if only distance from A to B is specified. On the
+output we format the B to A distance too.
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit afb1ea67769d88290499c5c6a0c34982bad6e9c9)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <6974ab2c0987840742965ea925adcc4395f72ec2.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ .../qemuxml2xmloutdata/numatune-distances.xml | 96 +++++++++++++++++++
+ tests/qemuxml2xmltest.c                       |  1 +
+ 2 files changed, 97 insertions(+)
+ create mode 100644 tests/qemuxml2xmloutdata/numatune-distances.xml
+
+diff --git a/tests/qemuxml2xmloutdata/numatune-distances.xml b/tests/qemuxml2xmloutdata/numatune-distances.xml
+new file mode 100644
+index 0000000000..48f89cb015
+--- /dev/null
++++ b/tests/qemuxml2xmloutdata/numatune-distances.xml
+@@ -0,0 +1,96 @@
++<domain type='qemu'>
++  <name>QEMUGuest</name>
++  <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid>
++  <memory unit='KiB'>8388608</memory>
++  <currentMemory unit='KiB'>8388608</currentMemory>
++  <vcpu placement='static'>12</vcpu>
++  <os>
++    <type arch='x86_64' machine='pc'>hvm</type>
++    <boot dev='hd'/>
++  </os>
++  <features>
++    <acpi/>
++    <apic/>
++    <pae/>
++  </features>
++  <cpu>
++    <numa>
++      <cell id='0' cpus='0,11' memory='2097152' unit='KiB'>
++        <distances>
++          <sibling id='0' value='10'/>
++          <sibling id='1' value='21'/>
++          <sibling id='2' value='31'/>
++          <sibling id='3' value='41'/>
++          <sibling id='4' value='51'/>
++          <sibling id='5' value='61'/>
++        </distances>
++      </cell>
++      <cell id='1' cpus='1,10' memory='2097152' unit='KiB'>
++        <distances>
++          <sibling id='0' value='21'/>
++          <sibling id='1' value='10'/>
++          <sibling id='2' value='21'/>
++          <sibling id='3' value='31'/>
++          <sibling id='4' value='41'/>
++          <sibling id='5' value='51'/>
++        </distances>
++      </cell>
++      <cell id='2' cpus='2,9' memory='2097152' unit='KiB'>
++        <distances>
++          <sibling id='0' value='31'/>
++          <sibling id='1' value='21'/>
++          <sibling id='2' value='10'/>
++          <sibling id='3' value='21'/>
++          <sibling id='4' value='31'/>
++          <sibling id='5' value='41'/>
++        </distances>
++      </cell>
++      <cell id='3' cpus='3,8' memory='2097152' unit='KiB'>
++        <distances>
++          <sibling id='0' value='41'/>
++          <sibling id='1' value='31'/>
++          <sibling id='2' value='21'/>
++          <sibling id='3' value='10'/>
++          <sibling id='4' value='21'/>
++          <sibling id='5' value='31'/>
++        </distances>
++      </cell>
++      <cell id='4' cpus='4,7' memory='2097152' unit='KiB'>
++        <distances>
++          <sibling id='0' value='51'/>
++          <sibling id='1' value='41'/>
++          <sibling id='2' value='31'/>
++          <sibling id='3' value='21'/>
++          <sibling id='4' value='10'/>
++          <sibling id='5' value='21'/>
++        </distances>
++      </cell>
++      <cell id='5' cpus='5-6' memory='2097152' unit='KiB'>
++        <distances>
++          <sibling id='0' value='61'/>
++          <sibling id='1' value='51'/>
++          <sibling id='2' value='41'/>
++          <sibling id='3' value='31'/>
++          <sibling id='4' value='21'/>
++          <sibling id='5' value='10'/>
++        </distances>
++      </cell>
++    </numa>
++  </cpu>
++  <clock offset='utc'/>
++  <on_poweroff>destroy</on_poweroff>
++  <on_reboot>restart</on_reboot>
++  <on_crash>restart</on_crash>
++  <devices>
++    <emulator>/usr/bin/qemu-system-x86_64</emulator>
++    <controller type='usb' index='0'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
++    </controller>
++    <controller type='pci' index='0' model='pci-root'/>
++    <input type='mouse' bus='ps2'/>
++    <input type='keyboard' bus='ps2'/>
++    <memballoon model='virtio'>
++      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
++    </memballoon>
++  </devices>
++</domain>
+diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
+index c8218e423e..6c3f5c4a9e 100644
+--- a/tests/qemuxml2xmltest.c
++++ b/tests/qemuxml2xmltest.c
+@@ -1104,6 +1104,7 @@ mymain(void)
+     DO_TEST("numatune-auto-prefer", NONE);
+     DO_TEST("numatune-memnode", QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_FILE);
+     DO_TEST("numatune-memnode-no-memory", QEMU_CAPS_OBJECT_MEMORY_FILE);
++    DO_TEST("numatune-distances", QEMU_CAPS_NUMA, QEMU_CAPS_NUMA_DIST);
+ 
+     DO_TEST("bios-nvram", NONE);
+     DO_TEST("bios-nvram-os-interleave", NONE);
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-rpc-add-support-for-filtering-acls-by-uint-params.patch b/SOURCES/libvirt-rpc-add-support-for-filtering-acls-by-uint-params.patch
new file mode 100644
index 0000000..78f2dcc
--- /dev/null
+++ b/SOURCES/libvirt-rpc-add-support-for-filtering-acls-by-uint-params.patch
@@ -0,0 +1,104 @@
+From ea90c1e23120e8bde86d22d83d179bc393bc2daa Mon Sep 17 00:00:00 2001
+Message-Id: <ea90c1e23120e8bde86d22d83d179bc393bc2daa@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Tue, 29 Sep 2020 14:43:04 +0200
+Subject: [PATCH] rpc: add support for filtering @acls by uint params
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+CVE-2020-25637
+
+Add a new field to @acl annotations for filtering by
+unsigned int parameters.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 50864dcda191eb35732dbd80fb6ca251a6bba923)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Message-Id: <7900a5f9e8479789a5cc427a85f385095e517e87.1601383236.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/remote/remote_protocol.x |  3 +++
+ src/rpc/gendispatch.pl       | 21 ++++++++++++++++++++-
+ 2 files changed, 23 insertions(+), 1 deletion(-)
+
+diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
+index 79cdb13a90..2527a78142 100644
+--- a/src/remote/remote_protocol.x
++++ b/src/remote/remote_protocol.x
+@@ -3805,6 +3805,7 @@ enum remote_procedure {
+      *
+      * - @acl: <object>:<permission>
+      * - @acl: <object>:<permission>:<flagname>
++     * - @acl: <object>:<permission>::<param>:<value>
+      *
+      *   Declare the access control requirements for the API. May be repeated
+      *   multiple times, if multiple rules are required.
+@@ -3814,6 +3815,8 @@ enum remote_procedure {
+      *     <permission> is one of the permissions in access/viraccessperm.h
+      *     <flagname> indicates the rule only applies if the named flag
+      *     is set in the API call
++     *     <param> and <value> can be used to check an unsigned int parameter
++     *     against value
+      *
+      * - @aclfilter: <object>:<permission>
+      *
+diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
+index 4cb9701e59..6a4f8074ad 100755
+--- a/src/rpc/gendispatch.pl
++++ b/src/rpc/gendispatch.pl
+@@ -2104,10 +2104,12 @@ elsif ($mode eq "client") {
+             my @acl;
+             foreach (@{$acl}) {
+                 my @bits = split /:/;
+-                push @acl, { object => $bits[0], perm => $bits[1], flags => $bits[2] }
++                push @acl, { object => $bits[0], perm => $bits[1], flags => $bits[2],
++                             param => $bits[3], value => $bits[4] }
+             }
+ 
+             my $checkflags = 0;
++            my $paramtocheck = undef;
+             for (my $i = 1 ; $i <= $#acl ; $i++) {
+                 if ($acl[$i]->{object} ne $acl[0]->{object}) {
+                     die "acl for '$call->{ProcName}' cannot check different objects";
+@@ -2115,6 +2117,9 @@ elsif ($mode eq "client") {
+                 if (defined $acl[$i]->{flags} && length $acl[$i]->{flags}) {
+                     $checkflags = 1;
+                 }
++                if (defined $acl[$i]->{param}) {
++                    $paramtocheck = $acl[$i]->{param};
++                }
+             }
+ 
+             my $apiname = $prefix . $call->{ProcName};
+@@ -2150,6 +2155,9 @@ elsif ($mode eq "client") {
+             if ($checkflags) {
+                 push @argdecls, "unsigned int flags";
+             }
++            if (defined $paramtocheck) {
++                push @argdecls, "unsigned int " . $paramtocheck;
++            }
+ 
+             my $ret;
+             my $pass;
+@@ -2210,6 +2218,17 @@ elsif ($mode eq "client") {
+                         }
+                         print "        ";
+                     }
++                    if (defined $acl->{param}) {
++                        my $param = $acl->{param};
++                        my $value = $acl->{value};
++                        if ($value =~ /^\!/) {
++                            $value = substr $value, 1;
++                            print "($param != ($value)) &&\n";
++                        } else {
++                            print "($param == ($value)) &&\n";
++                        }
++                        print "        ";
++                    }
+                     print "(rv = $method(" . join(", ", @argvars, $perm) . ")) <= 0) {\n";
+                     print "        virObjectUnref(mgr);\n";
+                     if ($action eq "Ensure") {
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-rpc-gendispatch-handle-empty-flags.patch b/SOURCES/libvirt-rpc-gendispatch-handle-empty-flags.patch
new file mode 100644
index 0000000..f279dc2
--- /dev/null
+++ b/SOURCES/libvirt-rpc-gendispatch-handle-empty-flags.patch
@@ -0,0 +1,51 @@
+From fa5b4100c32d3125eeb0d6b0024892af86ecddb0 Mon Sep 17 00:00:00 2001
+Message-Id: <fa5b4100c32d3125eeb0d6b0024892af86ecddb0@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Tue, 29 Sep 2020 14:43:03 +0200
+Subject: [PATCH] rpc: gendispatch: handle empty flags
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+CVE-2020-25637
+
+Prepare for omission of the <flagname> in remote_protocol.x
+@acl annotations:
+ @acl: <object>:<permission>:<flagname>
+so that we can add more fields after, e.g.:
+ @acl: <object>:<permission>::<field>
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 955029bd0ad7ef96000f529ac38204a8f4a96401)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Message-Id: <5fda9fc6cfe45eace10b8c2565a8b0c46b51f46c.1601383236.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/rpc/gendispatch.pl | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
+index 8656c8f205..4cb9701e59 100755
+--- a/src/rpc/gendispatch.pl
++++ b/src/rpc/gendispatch.pl
+@@ -2112,7 +2112,7 @@ elsif ($mode eq "client") {
+                 if ($acl[$i]->{object} ne $acl[0]->{object}) {
+                     die "acl for '$call->{ProcName}' cannot check different objects";
+                 }
+-                if (defined $acl[$i]->{flags}) {
++                if (defined $acl[$i]->{flags} && length $acl[$i]->{flags}) {
+                     $checkflags = 1;
+                 }
+             }
+@@ -2200,7 +2200,7 @@ elsif ($mode eq "client") {
+                     my $method = "virAccessManagerCheck" . $object;
+                     my $space = ' ' x length($method);
+                     print "    if (";
+-                    if (defined $acl->{flags}) {
++                    if (defined $acl->{flags} && length $acl->{flags}) {
+                         my $flags = $acl->{flags};
+                         if ($flags =~ /^\!/) {
+                             $flags = substr $flags, 1;
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-rpc-require-write-acl-for-guest-agent-in-virDomainInterfaceAddresses.patch b/SOURCES/libvirt-rpc-require-write-acl-for-guest-agent-in-virDomainInterfaceAddresses.patch
new file mode 100644
index 0000000..fdc0d5e
--- /dev/null
+++ b/SOURCES/libvirt-rpc-require-write-acl-for-guest-agent-in-virDomainInterfaceAddresses.patch
@@ -0,0 +1,72 @@
+From 48f74599ffc86aa632ee39aff1aa8459880ec283 Mon Sep 17 00:00:00 2001
+Message-Id: <48f74599ffc86aa632ee39aff1aa8459880ec283@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Tue, 29 Sep 2020 14:43:05 +0200
+Subject: [PATCH] rpc: require write acl for guest agent in
+ virDomainInterfaceAddresses
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+CVE-2020-25637
+
+Add a requirement for domain:write if source is set to
+VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT.
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
+(cherry picked from commit e4116eaa44cb366b59f7fe98f4b88d04c04970ad)
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+
+Conflicts: src/lxc/lxc_driver.c
+    The LXC implementation of the API was introduced
+    in libvirt 6.1.0, so it's not present downstream.
+Message-Id: <5fdc2ebf7621698c8136b354922c687fc09286de.1601383236.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/libxl/libxl_driver.c     | 2 +-
+ src/qemu/qemu_driver.c       | 2 +-
+ src/remote/remote_protocol.x | 1 +
+ 3 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
+index f021ec9c5d..1449795494 100644
+--- a/src/libxl/libxl_driver.c
++++ b/src/libxl/libxl_driver.c
+@@ -6318,7 +6318,7 @@ libxlDomainInterfaceAddresses(virDomainPtr dom,
+     if (!(vm = libxlDomObjFromDomain(dom)))
+         goto cleanup;
+ 
+-    if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def) < 0)
++    if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def, source) < 0)
+         goto cleanup;
+ 
+     if (virDomainObjCheckActive(vm) < 0)
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index f8a259e020..0f06974a1b 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -22240,7 +22240,7 @@ qemuDomainInterfaceAddresses(virDomainPtr dom,
+     if (!(vm = qemuDomainObjFromDomain(dom)))
+         goto cleanup;
+ 
+-    if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def) < 0)
++    if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def, source) < 0)
+         goto cleanup;
+ 
+     if (virDomainObjCheckActive(vm) < 0)
+diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
+index 2527a78142..fbd30085b2 100644
+--- a/src/remote/remote_protocol.x
++++ b/src/remote/remote_protocol.x
+@@ -6211,6 +6211,7 @@ enum remote_procedure {
+     /**
+      * @generate: none
+      * @acl: domain:read
++     * @acl: domain:write::source:VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT
+      */
+     REMOTE_PROC_DOMAIN_INTERFACE_ADDRESSES = 353,
+ 
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-tests-add-cgroup-nested-tests.patch b/SOURCES/libvirt-tests-add-cgroup-nested-tests.patch
new file mode 100644
index 0000000..300ab47
--- /dev/null
+++ b/SOURCES/libvirt-tests-add-cgroup-nested-tests.patch
@@ -0,0 +1,226 @@
+From c94691d796682d951ffa8fb3a4fcb985aae17d9b Mon Sep 17 00:00:00 2001
+Message-Id: <c94691d796682d951ffa8fb3a4fcb985aae17d9b@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Fri, 19 Feb 2021 13:34:00 +0100
+Subject: [PATCH] tests: add cgroup nested tests
+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: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 85099c339346e41f457234e8ad831841aef1d5e3)
+
+Conflicts:
+    tests/vircgrouptest.c
+        - missing upstream g_autofree rewrite
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <abf8f7673bd59c6e3d9b596cf9a86029b1f1e9c1.1613737828.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/vircgroupdata/systemd-legacy.cgroups    | 12 +++
+ tests/vircgroupdata/systemd-legacy.mounts     | 11 +++
+ .../vircgroupdata/systemd-legacy.self.cgroup  | 11 +++
+ tests/vircgroupdata/systemd-unified.cgroups   | 13 +++
+ tests/vircgroupdata/systemd-unified.mounts    |  1 +
+ .../vircgroupdata/systemd-unified.self.cgroup |  1 +
+ tests/vircgrouptest.c                         | 82 +++++++++++++++++++
+ 7 files changed, 131 insertions(+)
+ create mode 100644 tests/vircgroupdata/systemd-legacy.cgroups
+ create mode 100644 tests/vircgroupdata/systemd-legacy.mounts
+ create mode 100644 tests/vircgroupdata/systemd-legacy.self.cgroup
+ create mode 100644 tests/vircgroupdata/systemd-unified.cgroups
+ create mode 100644 tests/vircgroupdata/systemd-unified.mounts
+ create mode 100644 tests/vircgroupdata/systemd-unified.self.cgroup
+
+diff --git a/tests/vircgroupdata/systemd-legacy.cgroups b/tests/vircgroupdata/systemd-legacy.cgroups
+new file mode 100644
+index 0000000000..444354e3c8
+--- /dev/null
++++ b/tests/vircgroupdata/systemd-legacy.cgroups
+@@ -0,0 +1,12 @@
++#subsys_name	hierarchy	num_cgroups	enabled
++blkio       1       1       1
++cpu         2       1       1
++cpuacct     3       1       1
++cpuset      4       1       1
++devices     5       1       1
++freezer     6       1       1
++hugetlb     7       1       1
++memory      8       1       1
++net_cls     9       1       1
++perf_event  10      1       1
++pids        11      1       1
+diff --git a/tests/vircgroupdata/systemd-legacy.mounts b/tests/vircgroupdata/systemd-legacy.mounts
+new file mode 100644
+index 0000000000..23462e9e68
+--- /dev/null
++++ b/tests/vircgroupdata/systemd-legacy.mounts
+@@ -0,0 +1,11 @@
++cgroup /not/really/sys/fs/cgroup/blkio cgroup rw,seclabel,nosuid,nodev,noexec,relatime,blkio 0 0
++cgroup /not/really/sys/fs/cgroup/cpu cgroup rw,seclabel,nosuid,nodev,noexec,relatime,cpu 0 0
++cgroup /not/really/sys/fs/cgroup/cpuacct cgroup rw,seclabel,nosuid,nodev,noexec,relatime,cpuacct 0 0
++cgroup /not/really/sys/fs/cgroup/cpuset cgroup rw,seclabel,nosuid,nodev,noexec,relatime,cpuset 0 0
++cgroup /not/really/sys/fs/cgroup/devices cgroup rw,seclabel,nosuid,nodev,noexec,relatime,devices 0 0
++cgroup /not/really/sys/fs/cgroup/freezer cgroup rw,seclabel,nosuid,nodev,noexec,relatime,freezer 0 0
++cgroup /not/really/sys/fs/cgroup/hugetlb cgroup rw,seclabel,nosuid,nodev,noexec,relatime,hugetlb 0 0
++cgroup /not/really/sys/fs/cgroup/memory cgroup rw,seclabel,nosuid,nodev,noexec,relatime,memory 0 0
++cgroup /not/really/sys/fs/cgroup/net_cls cgroup rw,seclabel,nosuid,nodev,noexec,relatime,net_cls 0 0
++cgroup /not/really/sys/fs/cgroup/perf_event cgroup rw,seclabel,nosuid,nodev,noexec,relatime,perf_event 0 0
++cgroup /not/really/sys/fs/cgroup/pids cgroup rw,seclabel,nosuid,nodev,noexec,relatime,pids 0 0
+diff --git a/tests/vircgroupdata/systemd-legacy.self.cgroup b/tests/vircgroupdata/systemd-legacy.self.cgroup
+new file mode 100644
+index 0000000000..5c133a3c08
+--- /dev/null
++++ b/tests/vircgroupdata/systemd-legacy.self.cgroup
+@@ -0,0 +1,11 @@
++1:blkio:/libvirt
++2:cpu:/libvirt/emulator
++3:cpuacct:/libvirt/emulator
++4:cpuset:/libvirt/emulator
++5:devices:/libvirt
++6:freezer:/libvirt
++7:hugetlb:/
++8:memory:/libvirt
++9:net_cls:/libvirt
++10:perf_event:/libvirt
++11:pids:/
+diff --git a/tests/vircgroupdata/systemd-unified.cgroups b/tests/vircgroupdata/systemd-unified.cgroups
+new file mode 100644
+index 0000000000..e0d8a3561c
+--- /dev/null
++++ b/tests/vircgroupdata/systemd-unified.cgroups
+@@ -0,0 +1,13 @@
++#subsys_name	hierarchy	num_cgroups	enabled
++cpuset      0       1       1
++cpu         0       1       1
++cpuacct     0       1       1
++blkio       0       1       1
++memory      0       1       1
++devices     0       1       1
++freezer     0       1       1
++net_cls     0       1       1
++perf_event  0       1       1
++net_prio    0       1       1
++hugetlb     0       1       1
++pids        0       1       1
+diff --git a/tests/vircgroupdata/systemd-unified.mounts b/tests/vircgroupdata/systemd-unified.mounts
+new file mode 100644
+index 0000000000..8225f37f45
+--- /dev/null
++++ b/tests/vircgroupdata/systemd-unified.mounts
+@@ -0,0 +1 @@
++cgroup2 /not/really/sys/fs/cgroup cgroup2 rw,seclabel,nosuid,nodev,noexec,relatime,nsdelegate 0 0
+diff --git a/tests/vircgroupdata/systemd-unified.self.cgroup b/tests/vircgroupdata/systemd-unified.self.cgroup
+new file mode 100644
+index 0000000000..6007ce7e18
+--- /dev/null
++++ b/tests/vircgroupdata/systemd-unified.self.cgroup
+@@ -0,0 +1 @@
++0::/libvirt/emulator
+diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c
+index 2d6f52fb6e..aebb90c16c 100644
+--- a/tests/vircgrouptest.c
++++ b/tests/vircgrouptest.c
+@@ -636,6 +636,74 @@ static int testCgroupNewForSelfHybrid(const void *args G_GNUC_UNUSED)
+ }
+ 
+ 
++static int testCgroupNewForSelfSystemdLegacy(const void *args G_GNUC_UNUSED)
++{
++    virCgroupPtr cgroup = NULL;
++    int ret = -1;
++    const char *empty[VIR_CGROUP_CONTROLLER_LAST] = { 0 };
++    const char *mounts[VIR_CGROUP_CONTROLLER_LAST] = {
++        [VIR_CGROUP_CONTROLLER_BLKIO] = "/not/really/sys/fs/cgroup/blkio",
++        [VIR_CGROUP_CONTROLLER_CPU] = "/not/really/sys/fs/cgroup/cpu",
++        [VIR_CGROUP_CONTROLLER_CPUACCT] = "/not/really/sys/fs/cgroup/cpuacct",
++        [VIR_CGROUP_CONTROLLER_CPUSET] = "/not/really/sys/fs/cgroup/cpuset",
++        [VIR_CGROUP_CONTROLLER_DEVICES] = "/not/really/sys/fs/cgroup/devices",
++        [VIR_CGROUP_CONTROLLER_FREEZER] = "/not/really/sys/fs/cgroup/freezer",
++        [VIR_CGROUP_CONTROLLER_MEMORY] = "/not/really/sys/fs/cgroup/memory",
++        [VIR_CGROUP_CONTROLLER_NET_CLS] = "/not/really/sys/fs/cgroup/net_cls",
++        [VIR_CGROUP_CONTROLLER_PERF_EVENT] = "/not/really/sys/fs/cgroup/perf_event",
++    };
++    const char *placement[VIR_CGROUP_CONTROLLER_LAST] = {
++        [VIR_CGROUP_CONTROLLER_BLKIO] = "",
++        [VIR_CGROUP_CONTROLLER_CPU] = "",
++        [VIR_CGROUP_CONTROLLER_CPUACCT] = "",
++        [VIR_CGROUP_CONTROLLER_CPUSET] = "",
++        [VIR_CGROUP_CONTROLLER_DEVICES] = "",
++        [VIR_CGROUP_CONTROLLER_FREEZER] = "",
++        [VIR_CGROUP_CONTROLLER_MEMORY] = "",
++        [VIR_CGROUP_CONTROLLER_NET_CLS] = "",
++        [VIR_CGROUP_CONTROLLER_PERF_EVENT] = "",
++    };
++
++    if (virCgroupNewSelf(&cgroup) < 0) {
++        fprintf(stderr, "Cannot create cgroup for self\n");
++        goto cleanup;
++    }
++
++    ret = validateCgroup(cgroup, "", mounts, empty, placement, NULL, NULL, 0);
++
++ cleanup:
++    virCgroupFree(&cgroup);
++    return ret;
++}
++
++
++static int testCgroupNewForSelfSystemdUnified(const void *args G_GNUC_UNUSED)
++{
++    virCgroupPtr cgroup = NULL;
++    int ret = -1;
++    const char *empty[VIR_CGROUP_CONTROLLER_LAST] = { 0 };
++    unsigned int controllers =
++        (1 << VIR_CGROUP_CONTROLLER_CPU) |
++        (1 << VIR_CGROUP_CONTROLLER_CPUACCT) |
++        (1 << VIR_CGROUP_CONTROLLER_MEMORY) |
++        (1 << VIR_CGROUP_CONTROLLER_DEVICES) |
++        (1 << VIR_CGROUP_CONTROLLER_BLKIO);
++
++    if (virCgroupNewSelf(&cgroup) < 0) {
++        fprintf(stderr, "Cannot create cgroup for self\n");
++        goto cleanup;
++    }
++
++    ret = validateCgroup(cgroup, "", empty, empty, empty,
++                         "/not/really/sys/fs/cgroup", "",
++                         controllers);
++
++ cleanup:
++    virCgroupFree(&cgroup);
++    return ret;
++}
++
++
+ static int testCgroupAvailable(const void *args)
+ {
+     bool got = virCgroupAvailable();
+@@ -1125,6 +1193,20 @@ mymain(void)
+         ret = -1;
+     cleanupFakeFS(fakerootdir);
+ 
++    fakerootdir = initFakeFS("legacy", "systemd-legacy");
++    if (virTestRun("New cgroup for self (systemd-legacy)",
++                   testCgroupNewForSelfSystemdLegacy, NULL) < 0) {
++        ret = -1;
++    }
++    cleanupFakeFS(fakerootdir);
++
++    fakerootdir = initFakeFS("unified", "systemd-unified");
++    if (virTestRun("New cgroup for self (systemd-unified)",
++                   testCgroupNewForSelfSystemdUnified, NULL) < 0) {
++        ret = -1;
++    }
++    cleanupFakeFS(fakerootdir);
++
+     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+ 
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-tests-fix-iptables-test-case-commandline-options-in-virfirewalltest.c.patch b/SOURCES/libvirt-tests-fix-iptables-test-case-commandline-options-in-virfirewalltest.c.patch
new file mode 100644
index 0000000..60697f8
--- /dev/null
+++ b/SOURCES/libvirt-tests-fix-iptables-test-case-commandline-options-in-virfirewalltest.c.patch
@@ -0,0 +1,522 @@
+From 2439f55f8a44ae3bddde8098f3f6ea67ccfd1d9b Mon Sep 17 00:00:00 2001
+Message-Id: <2439f55f8a44ae3bddde8098f3f6ea67ccfd1d9b@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Fri, 15 Jan 2021 22:51:47 -0500
+Subject: [PATCH] tests: fix iptables test case commandline options in
+ virfirewalltest.c
+
+This test was created with all the commandlines erroneously having
+"--source-host", which is not a valid iptables option. The correct
+name for the option is "--source". However, since the test is just
+checking that the generated commandline matches what we told it to
+generate (and never actually runs iptables, as that would be a "Really
+Bad Idea"(tm)), the test has always succeeded. I only found it because
+I made a change to the code that caused the test to incorrectly try to
+run iptables during the test, and the error message I received was
+"odd" (it complained about the bad option, rather than complaining
+that I had insufficient privilege to run the command).
+
+https://bugzilla.redhat.com/1607929
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit e9693502fb63ce5ddd07d2599daddc563c422eed)
+Message-Id: <20210116035151.1066734-5-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ tests/virfirewalltest.c | 168 ++++++++++++++++++++--------------------
+ 1 file changed, 84 insertions(+), 84 deletions(-)
+
+diff --git a/tests/virfirewalltest.c b/tests/virfirewalltest.c
+index 1ec768d302..40e7f4f00b 100644
+--- a/tests/virfirewalltest.c
++++ b/tests/virfirewalltest.c
+@@ -206,8 +206,8 @@ testFirewallSingleGroup(const void *opaque)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n";
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source '!192.168.122.1' --jump REJECT\n";
+     const struct testFirewallData *data = opaque;
+ 
+     fwDisabled = data->fwDisabled;
+@@ -225,12 +225,12 @@ testFirewallSingleGroup(const void *opaque)
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "!192.168.122.1",
++                       "--source", "!192.168.122.1",
+                        "--jump", "REJECT", NULL);
+ 
+     if (virFirewallApply(fw) < 0)
+@@ -262,8 +262,8 @@ testFirewallRemoveRule(const void *opaque)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n";
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source '!192.168.122.1' --jump REJECT\n";
+     const struct testFirewallData *data = opaque;
+     virFirewallRulePtr fwrule;
+ 
+@@ -282,17 +282,17 @@ testFirewallRemoveRule(const void *opaque)
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     fwrule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                                 "-A", "INPUT", NULL);
+-    virFirewallRuleAddArg(fw, fwrule, "--source-host");
++    virFirewallRuleAddArg(fw, fwrule, "--source");
+     virFirewallRemoveRule(fw, fwrule);
+ 
+     fwrule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                                 "-A", "INPUT", NULL);
+-    virFirewallRuleAddArg(fw, fwrule, "--source-host");
++    virFirewallRuleAddArg(fw, fwrule, "--source");
+     virFirewallRuleAddArgFormat(fw, fwrule, "%s", "!192.168.122.1");
+     virFirewallRuleAddArgList(fw, fwrule, "--jump", "REJECT", NULL);
+ 
+@@ -325,9 +325,9 @@ testFirewallManyGroups(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"
+-        IPTABLES_PATH " -w -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source '!192.168.122.1' --jump REJECT\n"
++        IPTABLES_PATH " -w -A OUTPUT --source 192.168.122.1 --jump ACCEPT\n"
+         IPTABLES_PATH " -w -A OUTPUT --jump DROP\n";
+     const struct testFirewallData *data = opaque;
+ 
+@@ -346,19 +346,19 @@ testFirewallManyGroups(const void *opaque G_GNUC_UNUSED)
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "!192.168.122.1",
++                       "--source", "!192.168.122.1",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallStartTransaction(fw, 0);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "OUTPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+@@ -416,9 +416,9 @@ testFirewallIgnoreFailGroup(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -w -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -A OUTPUT --source 192.168.122.1 --jump ACCEPT\n"
+         IPTABLES_PATH " -w -A OUTPUT --jump DROP\n";
+     const struct testFirewallData *data = opaque;
+ 
+@@ -439,19 +439,19 @@ testFirewallIgnoreFailGroup(const void *opaque G_GNUC_UNUSED)
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.255",
++                       "--source", "192.168.122.255",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallStartTransaction(fw, 0);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "OUTPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+@@ -488,9 +488,9 @@ testFirewallIgnoreFailRule(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -w -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -A OUTPUT --source 192.168.122.1 --jump ACCEPT\n"
+         IPTABLES_PATH " -w -A OUTPUT --jump DROP\n";
+     const struct testFirewallData *data = opaque;
+ 
+@@ -511,18 +511,18 @@ testFirewallIgnoreFailRule(const void *opaque G_GNUC_UNUSED)
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_IPV4,
+                            true, NULL, NULL,
+                            "-A", "INPUT",
+-                           "--source-host", "192.168.122.255",
++                           "--source", "192.168.122.255",
+                            "--jump", "REJECT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "OUTPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+@@ -559,8 +559,8 @@ testFirewallNoRollback(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n";
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.255 --jump REJECT\n";
+     const struct testFirewallData *data = opaque;
+ 
+     fwDisabled = data->fwDisabled;
+@@ -580,17 +580,17 @@ testFirewallNoRollback(const void *opaque G_GNUC_UNUSED)
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.255",
++                       "--source", "192.168.122.255",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "!192.168.122.1",
++                       "--source", "!192.168.122.1",
+                        "--jump", "REJECT", NULL);
+ 
+     if (virFirewallApply(fw) == 0) {
+@@ -623,11 +623,11 @@ testFirewallSingleRollback(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n";
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -D INPUT --source 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source '!192.168.122.1' --jump REJECT\n";
+     const struct testFirewallData *data = opaque;
+ 
+     fwDisabled = data->fwDisabled;
+@@ -647,34 +647,34 @@ testFirewallSingleRollback(const void *opaque G_GNUC_UNUSED)
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.255",
++                       "--source", "192.168.122.255",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "!192.168.122.1",
++                       "--source", "!192.168.122.1",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallStartRollback(fw, 0);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-D", "INPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-D", "INPUT",
+-                       "--source-host", "192.168.122.255",
++                       "--source", "192.168.122.255",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-D", "INPUT",
+-                       "--source-host", "!192.168.122.1",
++                       "--source", "!192.168.122.1",
+                        "--jump", "REJECT", NULL);
+ 
+     if (virFirewallApply(fw) == 0) {
+@@ -707,10 +707,10 @@ testFirewallManyRollback(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n";
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source '!192.168.122.1' --jump REJECT\n";
+     const struct testFirewallData *data = opaque;
+ 
+     fwDisabled = data->fwDisabled;
+@@ -730,38 +730,38 @@ testFirewallManyRollback(const void *opaque G_GNUC_UNUSED)
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     virFirewallStartRollback(fw, 0);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-D", "INPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     virFirewallStartTransaction(fw, 0);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.255",
++                       "--source", "192.168.122.255",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "!192.168.122.1",
++                       "--source", "!192.168.122.1",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallStartRollback(fw, 0);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-D", "INPUT",
+-                       "--source-host", "192.168.122.255",
++                       "--source", "192.168.122.255",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-D", "INPUT",
+-                       "--source-host", "!192.168.122.1",
++                       "--source", "!192.168.122.1",
+                        "--jump", "REJECT", NULL);
+ 
+     if (virFirewallApply(fw) == 0) {
+@@ -794,14 +794,14 @@ testFirewallChainedRollback(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.127 --jump REJECT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.127 --jump REJECT\n"
+-        IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n"
+-        IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n";
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.127 --jump REJECT\n"
++        IPTABLES_PATH " -w -A INPUT --source '!192.168.122.1' --jump REJECT\n"
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source 192.168.122.127 --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source '!192.168.122.1' --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source '!192.168.122.1' --jump REJECT\n";
+     const struct testFirewallData *data = opaque;
+ 
+     fwDisabled = data->fwDisabled;
+@@ -821,14 +821,14 @@ testFirewallChainedRollback(const void *opaque G_GNUC_UNUSED)
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     virFirewallStartRollback(fw, 0);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-D", "INPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+ 
+@@ -836,24 +836,24 @@ testFirewallChainedRollback(const void *opaque G_GNUC_UNUSED)
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.127",
++                       "--source", "192.168.122.127",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "!192.168.122.1",
++                       "--source", "!192.168.122.1",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallStartRollback(fw, 0);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-D", "INPUT",
+-                       "--source-host", "192.168.122.127",
++                       "--source", "192.168.122.127",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-D", "INPUT",
+-                       "--source-host", "!192.168.122.1",
++                       "--source", "!192.168.122.1",
+                        "--jump", "REJECT", NULL);
+ 
+ 
+@@ -861,24 +861,24 @@ testFirewallChainedRollback(const void *opaque G_GNUC_UNUSED)
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.255",
++                       "--source", "192.168.122.255",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "!192.168.122.1",
++                       "--source", "!192.168.122.1",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallStartRollback(fw, VIR_FIREWALL_ROLLBACK_INHERIT_PREVIOUS);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-D", "INPUT",
+-                       "--source-host", "192.168.122.255",
++                       "--source", "192.168.122.255",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-D", "INPUT",
+-                       "--source-host", "!192.168.122.1",
++                       "--source", "!192.168.122.1",
+                        "--jump", "REJECT", NULL);
+ 
+     if (virFirewallApply(fw) == 0) {
+@@ -962,7 +962,7 @@ testFirewallQueryCallback(virFirewallPtr fw,
+     size_t i;
+     virFirewallAddRule(fw, layer,
+                        "-A", "INPUT",
+-                       "--source-host", "!192.168.122.129",
++                       "--source", "!192.168.122.129",
+                        "--jump", "REJECT", NULL);
+ 
+     for (i = 0; lines[i] != NULL; i++) {
+@@ -990,15 +990,15 @@ testFirewallQuery(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.127 --jump REJECT\n"
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.127 --jump REJECT\n"
+         IPTABLES_PATH " -w -L\n"
+         IPTABLES_PATH " -w -t nat -L\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.130 --jump REJECT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.129' --jump REJECT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.129' --jump REJECT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.128 --jump REJECT\n"
+-        IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n";
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.130 --jump REJECT\n"
++        IPTABLES_PATH " -w -A INPUT --source '!192.168.122.129' --jump REJECT\n"
++        IPTABLES_PATH " -w -A INPUT --source '!192.168.122.129' --jump REJECT\n"
++        IPTABLES_PATH " -w -A INPUT --source 192.168.122.128 --jump REJECT\n"
++        IPTABLES_PATH " -w -A INPUT --source '!192.168.122.1' --jump REJECT\n";
+     const struct testFirewallData *data = opaque;
+ 
+     expectedLineNum = 0;
+@@ -1020,14 +1020,14 @@ testFirewallQuery(const void *opaque G_GNUC_UNUSED)
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.1",
++                       "--source", "192.168.122.1",
+                        "--jump", "ACCEPT", NULL);
+ 
+     virFirewallStartTransaction(fw, 0);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.127",
++                       "--source", "192.168.122.127",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_IPV4,
+@@ -1043,7 +1043,7 @@ testFirewallQuery(const void *opaque G_GNUC_UNUSED)
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.130",
++                       "--source", "192.168.122.130",
+                        "--jump", "REJECT", NULL);
+ 
+ 
+@@ -1051,12 +1051,12 @@ testFirewallQuery(const void *opaque G_GNUC_UNUSED)
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "192.168.122.128",
++                       "--source", "192.168.122.128",
+                        "--jump", "REJECT", NULL);
+ 
+     virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4,
+                        "-A", "INPUT",
+-                       "--source-host", "!192.168.122.1",
++                       "--source", "!192.168.122.1",
+                        "--jump", "REJECT", NULL);
+ 
+     if (virFirewallApply(fw) < 0)
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-tests-qemuxml2argv-Use-existing-machine-type-for-numatune-distances-case.patch b/SOURCES/libvirt-tests-qemuxml2argv-Use-existing-machine-type-for-numatune-distances-case.patch
new file mode 100644
index 0000000..6d94707
--- /dev/null
+++ b/SOURCES/libvirt-tests-qemuxml2argv-Use-existing-machine-type-for-numatune-distances-case.patch
@@ -0,0 +1,59 @@
+From 5fad3414910beac08371233414939433644a92e8 Mon Sep 17 00:00:00 2001
+Message-Id: <5fad3414910beac08371233414939433644a92e8@dist-git>
+From: Peter Krempa <pkrempa@redhat.com>
+Date: Wed, 7 Oct 2020 18:45:31 +0200
+Subject: [PATCH] tests: qemuxml2argv: Use existing machine type for
+ 'numatune-distances' case
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Peter Krempa <pkrempa@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 99dcdf505e0856a5ebfb31f0047a1e24ec60b557)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Message-Id: <4af6d896e777397acd8b5945da6bf6bf071f2e98.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ tests/qemuxml2argvdata/numatune-distances.args | 4 ++--
+ tests/qemuxml2argvdata/numatune-distances.xml  | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tests/qemuxml2argvdata/numatune-distances.args b/tests/qemuxml2argvdata/numatune-distances.args
+index 895efeab15..a20b40b5c5 100644
+--- a/tests/qemuxml2argvdata/numatune-distances.args
++++ b/tests/qemuxml2argvdata/numatune-distances.args
+@@ -10,7 +10,7 @@ QEMU_AUDIO_DRV=none \
+ /usr/bin/qemu-system-x86_64 \
+ -name QEMUGuest \
+ -S \
+--machine xenfv,accel=tcg,usb=off,dump-guest-core=off \
++-machine pc,accel=tcg,usb=off,dump-guest-core=off \
+ -m 12288 \
+ -realtime mlock=off \
+ -smp 12,sockets=12,cores=1,threads=1 \
+@@ -66,4 +66,4 @@ server,nowait \
+ -rtc base=utc \
+ -no-shutdown \
+ -usb \
+--device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2
++-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
+diff --git a/tests/qemuxml2argvdata/numatune-distances.xml b/tests/qemuxml2argvdata/numatune-distances.xml
+index 0f33526b46..fa4de6aaf6 100644
+--- a/tests/qemuxml2argvdata/numatune-distances.xml
++++ b/tests/qemuxml2argvdata/numatune-distances.xml
+@@ -5,7 +5,7 @@
+   <currentMemory unit='KiB'>8388608</currentMemory>
+   <vcpu placement='static'>12</vcpu>
+   <os>
+-    <type arch='x86_64' machine='xenfv'>hvm</type>
++    <type arch='x86_64' machine='pc'>hvm</type>
+     <boot dev='hd'/>
+   </os>
+   <features>
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-udevProcessCSS-Check-if-def-driver-is-non-NULL.patch b/SOURCES/libvirt-udevProcessCSS-Check-if-def-driver-is-non-NULL.patch
new file mode 100644
index 0000000..82ec9ba
--- /dev/null
+++ b/SOURCES/libvirt-udevProcessCSS-Check-if-def-driver-is-non-NULL.patch
@@ -0,0 +1,69 @@
+From 32957eca8129f926d205310ee7efbc1168e8ebdc Mon Sep 17 00:00:00 2001
+Message-Id: <32957eca8129f926d205310ee7efbc1168e8ebdc@dist-git>
+From: Marc Hartmayer <mhartmay@linux.ibm.com>
+Date: Thu, 8 Oct 2020 11:07:00 -0400
+Subject: [PATCH] udevProcessCSS: Check if def->driver is non-NULL
+
+Don't process subchannel devices where `def->driver` is not set. This
+fixes the following segfault:
+
+Thread 21 "nodedev-init" received signal SIGSEGV, Segmentation fault.
+[Switching to Thread 0x3ffb08fc910 (LWP 64303)]
+(gdb) bt
+ #0  0x000003fffd1272b4 in __strcmp_vx () at /lib64/libc.so.6
+ #1  0x000003ffc260c3a8 in udevProcessCSS (device=0x3ff9018d130, def=0x3ff90194a90)
+ #2  0x000003ffc260cb78 in udevGetDeviceDetails (device=0x3ff9018d130, def=0x3ff90194a90)
+ #3  0x000003ffc260d126 in udevAddOneDevice (device=0x3ff9018d130)
+ #4  0x000003ffc260d414 in udevProcessDeviceListEntry (udev=0x3ffa810d800, list_entry=0x3ff90001990)
+ #5  0x000003ffc260d638 in udevEnumerateDevices (udev=0x3ffa810d800)
+ #6  0x000003ffc260e08e in nodeStateInitializeEnumerate (opaque=0x3ffa810d800)
+ #7  0x000003fffdaa14b6 in virThreadHelper (data=0x3ffa810df00)
+ #8  0x000003fffc309ed6 in start_thread ()
+ #9  0x000003fffd185e66 in thread_start ()
+(gdb) p *def
+$2 = {
+  name = 0x0,
+  sysfs_path = 0x3ff90198e80 "/sys/devices/css0/0.0.ff40",
+  parent = 0x0,
+  parent_sysfs_path = 0x0,
+  parent_wwnn = 0x0,
+  parent_wwpn = 0x0,
+  parent_fabric_wwn = 0x0,
+  driver = 0x0,
+  devnode = 0x0,
+  devlinks = 0x3ff90194670,
+  caps = 0x3ff90194380
+}
+
+Fixes: 05e6cdafa6e0 ("node_device: detect CSS devices")
+Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
+(cherry picked from commit cb09344a2cccc0cc9bcefa3cb53d7af45ba92631)
+https://bugzilla.redhat.com/show_bug.cgi?id=1853289
+https://bugzilla.redhat.com/show_bug.cgi?id=1865932
+Message-Id: <20201008150700.52157-6-bfiuczyn@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+---
+ src/node_device/node_device_udev.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
+index b6b28bc35a..88cf1edf50 100644
+--- a/src/node_device/node_device_udev.c
++++ b/src/node_device/node_device_udev.c
+@@ -1130,8 +1130,9 @@ udevProcessCSS(struct udev_device *device,
+                virNodeDeviceDefPtr def)
+ {
+     /* only process IO subchannel and vfio-ccw devices to keep the list sane */
+-    if (STRNEQ(def->driver, "io_subchannel") &&
+-        STRNEQ(def->driver, "vfio_ccw"))
++    if (!def->driver ||
++        (STRNEQ(def->driver, "io_subchannel") &&
++         STRNEQ(def->driver, "vfio_ccw")))
+         return -1;
+ 
+     if (udevGetCCWAddress(def->sysfs_path, &def->caps->data) < 0)
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-util-Add-phys_port_name-support-on-virPCIGetNetName.patch b/SOURCES/libvirt-util-Add-phys_port_name-support-on-virPCIGetNetName.patch
new file mode 100644
index 0000000..2cbe85e
--- /dev/null
+++ b/SOURCES/libvirt-util-Add-phys_port_name-support-on-virPCIGetNetName.patch
@@ -0,0 +1,228 @@
+From cfe170216accf60938ff4ea9440a4ac78b0bd83f Mon Sep 17 00:00:00 2001
+Message-Id: <cfe170216accf60938ff4ea9440a4ac78b0bd83f@dist-git>
+From: Dmytro Linkin <dlinkin@nvidia.com>
+Date: Thu, 28 Jan 2021 23:17:29 -0500
+Subject: [PATCH] util: Add phys_port_name support on virPCIGetNetName
+
+virPCIGetNetName is used to get the name of the netdev associated with
+a particular PCI device. This is used when we have a VF name, but need
+the PF name in order to send a netlink command (e.g. in order to
+get/set the MAC address of the VF).
+
+In simple cases there is a single netdev associated with any PCI
+device, so it is easy to figure out the PF netdev for a VF - just look
+for the PCI device that has the VF listed in its "virtfns" directory;
+the only name in the "net" subdirectory of that PCI device's sysfs
+directory is the PF netdev that is upstream of the VF in question.
+
+In some cases there can be more than one netdev in a PCI device's net
+directory though. In the past, the only case of this was for SR-IOV
+NICs that could have multiple PF's per PCI device. In this case, all
+PF netdevs associated with a PCI address would be listed in the "net"
+subdirectory of the PCI device's directory in sysfs. At the same time,
+all VF netdevs and all PF netdevs have a phys_port_id in their sysfs,
+so the way to learn the correct PF netdev for a particular VF netdev
+is to search through the list of devices in the net subdirectory of
+the PF's PCI device, looking for the one netdev with a "phys_port_id"
+matching that of the VF netdev.
+
+But starting in kernel 5.8, the NVIDIA Mellanox driver began linking
+the VFs' representor netdevs to the PF PCI address [1], and so the VF
+representor netdevs would also show up in the net
+subdirectory. However, all of the devices that do so also only have a
+single PF netdev for any given PCI address.
+
+This means that the net directory of the PCI device can still hold
+multiple net devices, but only one of them will be the PF netdev (the
+others are VF representors):
+
+$ ls '/sys/bus/pci/devices/0000:82:00.0/net'
+ens1f0  eth0  eth1
+
+In this case the way to find the PF device is to look at the
+"phys_port_name" attribute of each netdev in sysfs. All PF devices
+have a phys_port_name matching a particular regex
+
+  (p[0-9]+$)|(p[0-9]+s[0-9]+$)
+
+Since there can only be one PF in the entire list of devices, once we
+match that regex, we've found the PF netdev.
+
+[1] - https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/
+      commit/?id=123f0f53dd64b67e34142485fe866a8a581f12f1
+
+Resolves: https://bugzilla.redhat.com/1918708
+Co-Authored-by: Moshe Levi <moshele@nvidia.com>
+Signed-off-by: Dmytro Linkin <dlinkin@nvidia.com>
+Reviewed-by: Adrian Chiris <adrianc@nvidia.com>
+Reviewed-by: Laine Stump <laine@redhat.com>
+(cherry picked from commit 5b1c525b1f3608156884aed0dc5e925306c1e260)
+
+Conflicts: src/util/virpci.c - upstream all DIR* were converted to use
+    g_autoptr, which permitted virPCIGetNetName() to be
+    simplified. Unfortunately, backporting this refactor would require
+    backporting an ever-ballooning set of patches, making the
+    possibility of causing a regression a very real danger. Instead,
+    one small refactor of virPCIGetName() that didn't affect any other
+    functions was backported, and this patch (adding phys_port_name
+    support) resolved the remaining conflicts by mimicking the current
+    upstream version of the function, but with all "return 0" replaced
+    by "ret = 0; goto cleanup;" and all "return -1" replaced by "goto
+    cleanup;" (the code at cleanup: just closes the DIR* and returns
+    the current value of ret). This will assure identical behavior to
+    upstream.
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20210129041729.1076345-4-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virpci.c | 93 ++++++++++++++++++++++++++++-------------------
+ src/util/virpci.h |  5 +++
+ 2 files changed, 61 insertions(+), 37 deletions(-)
+
+diff --git a/src/util/virpci.c b/src/util/virpci.c
+index 00377eed31..d5c038b7fe 100644
+--- a/src/util/virpci.c
++++ b/src/util/virpci.c
+@@ -2424,9 +2424,9 @@ virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr addr,
+  * virPCIGetNetName:
+  * @device_link_sysfs_path: sysfs path to the PCI device
+  * @idx: used to choose which netdev when there are several
+- *       (ignored if physPortID is set)
++ *       (ignored if physPortID is set or physPortName is available)
+  * @physPortID: match this string in the netdev's phys_port_id
+- *       (or NULL to ignore and use idx instead)
++ *       (or NULL to ignore and use phys_port_name or idx instead)
+  * @netname: used to return the name of the netdev
+  *       (set to NULL (but returns success) if there is no netdev)
+  *
+@@ -2460,6 +2460,14 @@ virPCIGetNetName(const char *device_link_sysfs_path,
+     }
+ 
+     while (virDirRead(dir, &entry, pcidev_sysfs_net_path) > 0) {
++        /* save the first entry we find to use as a failsafe
++         * in case we don't match the phys_port_id. This is
++         * needed because some NIC drivers (e.g. i40e)
++         * implement phys_port_id for PFs, but not for VFs
++         */
++        if (!firstEntryName)
++            firstEntryName = g_strdup(entry->d_name);
++
+         /* if the caller sent a physPortID, compare it to the
+          * physportID of this netdev. If not, look for entry[idx].
+          */
+@@ -2470,50 +2478,61 @@ virPCIGetNetName(const char *device_link_sysfs_path,
+                 goto cleanup;
+ 
+             /* if this one doesn't match, keep looking */
+-            if (STRNEQ_NULLABLE(physPortID, thisPhysPortID)) {
+-                /* save the first entry we find to use as a failsafe
+-                 * in case we don't match the phys_port_id. This is
+-                 * needed because some NIC drivers (e.g. i40e)
+-                 * implement phys_port_id for PFs, but not for VFs
+-                 */
+-                if (!firstEntryName)
+-                    firstEntryName = g_strdup(entry->d_name);
+-
++            if (STRNEQ_NULLABLE(physPortID, thisPhysPortID))
+                 continue;
+-            }
++
+         } else {
+-            if (i++ < idx)
+-                continue;
+-        }
++            /* Most switch devices use phys_port_name instead of
++             * phys_port_id.
++             * NOTE: VFs' representors net devices can be linked to PF's PCI
++             * device, which mean that there'll be multiple net devices
++             * instances and to get a proper net device need to match on
++             * specific regex.
++             * To get PF netdev, for ex., used following regex:
++             * "(p[0-9]+$)|(p[0-9]+s[0-9]+$)"
++             * or to get exact VF's netdev next regex is used:
++             * "pf0vf1$"
++             */
++            g_autofree char *thisPhysPortName = NULL;
+ 
+-        *netname = g_strdup(entry->d_name);
++            if (virNetDevGetPhysPortName(entry->d_name, &thisPhysPortName) < 0)
++                goto cleanup;
+ 
+-        ret = 0;
+-        break;
+-    }
++            if (thisPhysPortName) {
++
++                /* if this one doesn't match, keep looking */
++                if (!virStringMatch(thisPhysPortName, VIR_PF_PHYS_PORT_NAME_REGEX))
++                    continue;
+ 
+-    if (ret < 0) {
+-        if (physPortID) {
+-            if (firstEntryName) {
+-                /* we didn't match the provided phys_port_id, but this
+-                 * is probably because phys_port_id isn't implemented
+-                 * for this NIC driver, so just return the first
+-                 * (probably only) netname we found.
+-                 */
+-                *netname = firstEntryName;
+-                firstEntryName = NULL;
+-                ret = 0;
+             } else {
+-                virReportError(VIR_ERR_INTERNAL_ERROR,
+-                               _("Could not find network device with "
+-                                 "phys_port_id '%s' under PCI device at %s"),
+-                               physPortID, device_link_sysfs_path);
++
++                if (i++ < idx)
++                    continue;
+             }
+-        } else {
+-            ret = 0; /* no netdev at the given index is *not* an error */
+         }
++
++        *netname = g_strdup(entry->d_name);
++        ret = 0;
++        goto cleanup;
+     }
+- cleanup:
++
++    if (firstEntryName) {
++        /* we didn't match the provided phys_port_id / find a
++         * phys_port_name matching VIR_PF_PHYS_PORT_NAME_REGEX / find
++         * as many net devices as the value of idx, but this is
++         * probably because phys_port_id / phys_port_name isn't
++         * implemented for this NIC driver, so just return the first
++         * (probably only) netname we found.
++         */
++        *netname = g_steal_pointer(&firstEntryName);
++        ret = 0;
++        goto cleanup;
++    }
++
++    virReportError(VIR_ERR_INTERNAL_ERROR,
++                   _("Could not find any network device under PCI device at %s"),
++                   device_link_sysfs_path);
++cleanup:
+     VIR_DIR_CLOSE(dir);
+     return ret;
+ }
+diff --git a/src/util/virpci.h b/src/util/virpci.h
+index f6796fc422..e47c766918 100644
+--- a/src/util/virpci.h
++++ b/src/util/virpci.h
+@@ -49,6 +49,11 @@ struct _virZPCIDeviceAddress {
+ 
+ #define VIR_PCI_DEVICE_ADDRESS_FMT "%04x:%02x:%02x.%d"
+ 
++/* Represents format of PF's phys_port_name in switchdev mode:
++ * 'p%u' or 'p%us%u'. New line checked since value is readed from sysfs file.
++ */
++#define VIR_PF_PHYS_PORT_NAME_REGEX  "(p[0-9]+$)|(p[0-9]+s[0-9]+$)"
++
+ struct _virPCIDeviceAddress {
+     unsigned int domain;
+     unsigned int bus;
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-util-add-virNetDevGetPhysPortName.patch b/SOURCES/libvirt-util-add-virNetDevGetPhysPortName.patch
new file mode 100644
index 0000000..15a794f
--- /dev/null
+++ b/SOURCES/libvirt-util-add-virNetDevGetPhysPortName.patch
@@ -0,0 +1,143 @@
+From 1b2014e2206b30a743a75908a129e444761726a7 Mon Sep 17 00:00:00 2001
+Message-Id: <1b2014e2206b30a743a75908a129e444761726a7@dist-git>
+From: Moshe Levi <moshele@nvidia.com>
+Date: Thu, 28 Jan 2021 23:17:27 -0500
+Subject: [PATCH] util: add virNetDevGetPhysPortName
+
+This commit add virNetDevGetPhysPortName to read netdevice
+phys_port_name from sysfs. It also refactor the code so
+virNetDevGetPhysPortName and virNetDevGetPhysPortID will use
+same method to read the netdevice sysfs.
+
+https://bugzilla.redhat.com/1918708
+Signed-off-by: Moshe Levi <moshele@nvidia.com>
+Reviewed-by: Laine Stump <laine@redhat.com>
+(cherry picked from commit 97ebb982453bc23759c5f180799d6f2207b81c80)
+
+Conflicts: src/util/virnetdev.c was converted to use g_autofree upstream.
+    This patch removes the need for the g_autofreed variable.
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20210129041729.1076345-2-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virnetdev.c | 72 +++++++++++++++++++++++++++++++++-----------
+ src/util/virnetdev.h |  4 +++
+ 2 files changed, 59 insertions(+), 17 deletions(-)
+
+diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
+index e2aad07c24..52c9343d63 100644
+--- a/src/util/virnetdev.c
++++ b/src/util/virnetdev.c
+@@ -1143,6 +1143,29 @@ virNetDevGetPCIDevice(const char *devName)
+ }
+ 
+ 
++/* A wrapper to get content of file from ifname SYSFS_NET_DIR
++ */
++static int
++virNetDevGetSysfsFileValue(const char *ifname,
++                           const char *fileName,
++                           char **sysfsFileData)
++{
++    g_autofree char *sysfsFile = NULL;
++
++    *sysfsFileData = NULL;
++
++    if (virNetDevSysfsFile(&sysfsFile, ifname, fileName) < 0)
++        return -1;
++
++    /* a failure to read just means the driver doesn't support
++     * <fileName>, so set success now and ignore the return from
++     * virFileReadAllQuiet().
++     */
++
++    ignore_value(virFileReadAllQuiet(sysfsFile, 1024, sysfsFileData));
++    return 0;
++}
++
+ /**
+  * virNetDevGetPhysPortID:
+  *
+@@ -1161,25 +1184,29 @@ int
+ virNetDevGetPhysPortID(const char *ifname,
+                        char **physPortID)
+ {
+-    int ret = -1;
+-    char *physPortIDFile = NULL;
+-
+-    *physPortID = NULL;
+-
+-    if (virNetDevSysfsFile(&physPortIDFile, ifname, "phys_port_id") < 0)
+-        goto cleanup;
+-
+-    /* a failure to read just means the driver doesn't support
+-     * phys_port_id, so set success now and ignore the return from
+-     * virFileReadAllQuiet().
+-     */
+-    ret = 0;
++    return virNetDevGetSysfsFileValue(ifname, "phys_port_id", physPortID);
++}
+ 
+-    ignore_value(virFileReadAllQuiet(physPortIDFile, 1024, physPortID));
+ 
+- cleanup:
+-    VIR_FREE(physPortIDFile);
+-    return ret;
++/**
++ * virNetDevGetPhysPortName:
++ *
++ * @ifname: name of a netdev
++ *
++ * @physPortName: pointer to char* that will receive @ifname's
++ *                phys_port_name from sysfs (null terminated
++ *                string). Could be NULL if @ifname's net driver doesn't
++ *                support phys_port_name (most netdev drivers
++ *                don't). Caller is responsible for freeing the string
++ *                when finished.
++ *
++ * Returns 0 on success or -1 on failure.
++ */
++int
++virNetDevGetPhysPortName(const char *ifname,
++                         char **physPortName)
++{
++    return virNetDevGetSysfsFileValue(ifname, "phys_port_name", physPortName);
+ }
+ 
+ 
+@@ -1461,6 +1488,17 @@ virNetDevGetPhysPortID(const char *ifname G_GNUC_UNUSED,
+     return 0;
+ }
+ 
++int
++virNetDevGetPhysPortName(const char *ifname G_GNUC_UNUSED,
++                       char **physPortName)
++{
++    /* this actually should never be called, and is just here to
++     * satisfy the linker.
++     */
++    *physPortName = NULL;
++    return 0;
++}
++
+ int
+ virNetDevGetVirtualFunctions(const char *pfname G_GNUC_UNUSED,
+                              char ***vfname G_GNUC_UNUSED,
+diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h
+index 24b41498ed..26fe76cc2c 100644
+--- a/src/util/virnetdev.h
++++ b/src/util/virnetdev.h
+@@ -227,6 +227,10 @@ int virNetDevGetPhysPortID(const char *ifname,
+                            char **physPortID)
+     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
+     G_GNUC_WARN_UNUSED_RESULT;
++int virNetDevGetPhysPortName(const char *ifname,
++                           char **physPortName)
++    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
++    G_GNUC_WARN_UNUSED_RESULT;
+ 
+ int virNetDevGetVirtualFunctions(const char *pfname,
+                                  char ***vfname,
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-util-always-check-for-ebtables-iptables-binaries-even-when-using-firewalld.patch b/SOURCES/libvirt-util-always-check-for-ebtables-iptables-binaries-even-when-using-firewalld.patch
new file mode 100644
index 0000000..f4fe465
--- /dev/null
+++ b/SOURCES/libvirt-util-always-check-for-ebtables-iptables-binaries-even-when-using-firewalld.patch
@@ -0,0 +1,108 @@
+From 36a12736f39da72dba98b843def645e5e4ed0afb Mon Sep 17 00:00:00 2001
+Message-Id: <36a12736f39da72dba98b843def645e5e4ed0afb@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Fri, 15 Jan 2021 22:51:49 -0500
+Subject: [PATCH] util: always check for ebtables/iptables binaries, even when
+ using firewalld
+
+Even though *we* don't call ebtables/iptables/ip6tables (yet) when the
+firewalld backend is selected, firewalld does, so these binaries need
+to be there; let's check for them. (Also, the patch after this one is
+going to start execing those binaries directly rather than via
+firewalld).
+
+https://bugzilla.redhat.com/1607929
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 56dd128bd06c38fab4256a098124d47d803e919a)
+Message-Id: <20210116035151.1066734-7-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virfirewall.c | 56 ++++++++++++++++++++----------------------
+ 1 file changed, 26 insertions(+), 30 deletions(-)
+
+diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c
+index 2e3b02402e..520d515c11 100644
+--- a/src/util/virfirewall.c
++++ b/src/util/virfirewall.c
+@@ -100,24 +100,38 @@ VIR_ONCE_GLOBAL_INIT(virFirewall);
+ static int
+ virFirewallValidateBackend(virFirewallBackend backend)
+ {
+-    VIR_DEBUG("Validating backend %d", backend);
++    const char *commands[] = {
++        IPTABLES_PATH, IP6TABLES_PATH, EBTABLES_PATH
++    };
++    size_t i;
++
++    for (i = 0; i < G_N_ELEMENTS(commands); i++) {
++        if (!virFileIsExecutable(commands[i])) {
++            virReportSystemError(errno,
++                                 _("%s not available, firewall backend will not function"),
++                                 commands[i]);
++            return -1;
++        }
++    }
++    VIR_DEBUG("found iptables/ip6tables/ebtables");
++
+     if (backend == VIR_FIREWALL_BACKEND_AUTOMATIC ||
+         backend == VIR_FIREWALL_BACKEND_FIREWALLD) {
+         int rv = virFirewallDIsRegistered();
+ 
+         VIR_DEBUG("Firewalld is registered ? %d", rv);
+-        if (rv < 0) {
+-            if (rv == -2) {
+-                if (backend == VIR_FIREWALL_BACKEND_FIREWALLD) {
+-                    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+-                                   _("firewalld firewall backend requested, but service is not running"));
+-                    return -1;
+-                } else {
+-                    VIR_DEBUG("firewalld service not running, trying direct backend");
+-                    backend = VIR_FIREWALL_BACKEND_DIRECT;
+-                }
+-            } else {
++
++        if (rv == -1)
++            return -1;
++
++        if (rv == -2) {
++            if (backend == VIR_FIREWALL_BACKEND_FIREWALLD) {
++                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
++                               _("firewalld backend requested, but service is not running"));
+                 return -1;
++            } else {
++                VIR_DEBUG("firewalld service not running, using direct backend");
++                backend = VIR_FIREWALL_BACKEND_DIRECT;
+             }
+         } else {
+             VIR_DEBUG("firewalld service running, using firewalld backend");
+@@ -125,25 +139,7 @@ virFirewallValidateBackend(virFirewallBackend backend)
+         }
+     }
+ 
+-    if (backend == VIR_FIREWALL_BACKEND_DIRECT) {
+-        const char *commands[] = {
+-            IPTABLES_PATH, IP6TABLES_PATH, EBTABLES_PATH
+-        };
+-        size_t i;
+-
+-        for (i = 0; i < G_N_ELEMENTS(commands); i++) {
+-            if (!virFileIsExecutable(commands[i])) {
+-                virReportSystemError(errno,
+-                                     _("direct firewall backend requested, but %s is not available"),
+-                                     commands[i]);
+-                return -1;
+-            }
+-        }
+-        VIR_DEBUG("found iptables/ip6tables/ebtables, using direct backend");
+-    }
+-
+     currentBackend = backend;
+-
+     return 0;
+ }
+ 
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-util-assign-tap-device-names-using-a-monotonically-increasing-integer.patch b/SOURCES/libvirt-util-assign-tap-device-names-using-a-monotonically-increasing-integer.patch
new file mode 100644
index 0000000..1a1e009
--- /dev/null
+++ b/SOURCES/libvirt-util-assign-tap-device-names-using-a-monotonically-increasing-integer.patch
@@ -0,0 +1,280 @@
+From 37b1acb1c820421d62b1416d90138bae7961bfb7 Mon Sep 17 00:00:00 2001
+Message-Id: <37b1acb1c820421d62b1416d90138bae7961bfb7@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Sat, 12 Dec 2020 22:04:52 -0500
+Subject: [PATCH] util: assign tap device names using a monotonically
+ increasing integer
+
+When creating a standard tap device, if provided with an ifname that
+contains "%d", rather than taking that literally as the name to use
+for the new device, the kernel will instead use that string as a
+template, and search for the lowest number that could be put in place
+of %d and produce an otherwise unused and unique name for the new
+device. For example, if there is no tap device name given in the XML,
+libvirt will always send "vnet%d" as the device name, and the kernel
+will create new devices named "vnet0", "vnet1", etc. If one of those
+devices is deleted, creating a "hole" in the name list, the kernel
+will always attempt to reuse the name in the hole first before using a
+name with a higher number (i.e. it finds the lowest possible unused
+number).
+
+The problem with this, as described in the previous patch dealing with
+macvtap device naming, is that it makes "immediate reuse" of a newly
+freed tap device name *much* more common, and in the aftermath of
+deleting a tap device, there is some other necessary cleanup of things
+which are named based on the device name (nwfilter rules, bandwidth
+rules, OVS switch ports, to name a few) that could end up stomping
+over the top of the setup of a new device of the same name for a
+different guest.
+
+Since the kernel "create a name based on a template" functionality for
+tap devices doesn't exist for macvtap, this patch for standard tap
+devices is a bit different from the previous patch for macvtap - in
+particular there was no previous "bitmap ID reservation system" or
+overly-complex retry loop that needed to be removed. We simply find
+and unused name, and pass that name on to the kernel instead of
+"vnet%d".
+
+This counter is also wrapped when either it gets to INT_MAX or if the
+full name would overflow IFNAMSIZ-1 characters. In the case of
+"vnet%d" and a 32 bit int, we would reach INT_MAX first, but possibly
+someday someone will change the name from vnet to something else.
+
+(NB: It is still possible for a user to provide their own
+parameterized template name (e.g. "mytap%d") in the XML, and libvirt
+will just pass that through to the kernel as it always has.)
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 95089f481e003d971fe0a082018216c58c1b80e5)
+
+https://bugzilla.redhat.com/1874304
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20201213030453.48851-3-laine@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/libvirt_private.syms |   1 +
+ src/qemu/qemu_process.c  |  20 +++++++-
+ src/util/virnetdevtap.c  | 108 ++++++++++++++++++++++++++++++++++++++-
+ src/util/virnetdevtap.h  |   4 ++
+ 4 files changed, 130 insertions(+), 3 deletions(-)
+
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 1c66c40f86..d6598c2514 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -2638,6 +2638,7 @@ virNetDevTapGetName;
+ virNetDevTapGetRealDeviceName;
+ virNetDevTapInterfaceStats;
+ virNetDevTapReattachBridge;
++virNetDevTapReserveName;
+ 
+ 
+ # util/virnetdevveth.h
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index b49a463c02..f90096e68d 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -3287,8 +3287,26 @@ qemuProcessNotifyNets(virDomainDefPtr def)
+          * domain to be unceremoniously killed, which would be *very*
+          * impolite.
+          */
+-        if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT)
++        switch (virDomainNetGetActualType(net)) {
++        case VIR_DOMAIN_NET_TYPE_DIRECT:
+             virNetDevMacVLanReserveName(net->ifname);
++            break;
++        case VIR_DOMAIN_NET_TYPE_BRIDGE:
++        case VIR_DOMAIN_NET_TYPE_NETWORK:
++        case VIR_DOMAIN_NET_TYPE_ETHERNET:
++            virNetDevTapReserveName(net->ifname);
++            break;
++        case VIR_DOMAIN_NET_TYPE_USER:
++        case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
++        case VIR_DOMAIN_NET_TYPE_SERVER:
++        case VIR_DOMAIN_NET_TYPE_CLIENT:
++        case VIR_DOMAIN_NET_TYPE_MCAST:
++        case VIR_DOMAIN_NET_TYPE_INTERNAL:
++        case VIR_DOMAIN_NET_TYPE_HOSTDEV:
++        case VIR_DOMAIN_NET_TYPE_UDP:
++        case VIR_DOMAIN_NET_TYPE_LAST:
++            break;
++        }
+ 
+         if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+             if (!conn && !(conn = virGetConnectNetwork()))
+diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c
+index 6a16b58d60..fd4b70df30 100644
+--- a/src/util/virnetdevtap.c
++++ b/src/util/virnetdevtap.c
+@@ -45,11 +45,51 @@
+ #if defined(HAVE_GETIFADDRS) && defined(AF_LINK)
+ # include <ifaddrs.h>
+ #endif
++#include <math.h>
+ 
+ #define VIR_FROM_THIS VIR_FROM_NONE
+ 
+ VIR_LOG_INIT("util.netdevtap");
+ 
++virMutex virNetDevTapCreateMutex = VIR_MUTEX_INITIALIZER;
++static int virNetDevTapLastID = -1; /* not "unsigned" because callers use %d */
++
++
++/**
++ * virNetDevTapReserveName:
++ * @name: name of an existing tap device
++ *
++ * Set the value of virNetDevTapLastID to assure that any new tap
++ * device created with an autogenerated name will use a number higher
++ * than the number in the given tap device name.
++ *
++ * Returns nothing.
++ */
++void
++virNetDevTapReserveName(const char *name)
++{
++    unsigned int id;
++    const char *idstr = NULL;
++
++
++    if (STRPREFIX(name, VIR_NET_GENERATED_TAP_PREFIX)) {
++
++        VIR_INFO("marking device in use: '%s'", name);
++
++        idstr = name + strlen(VIR_NET_GENERATED_TAP_PREFIX);
++
++        if (virStrToLong_ui(idstr, NULL, 10, &id) >= 0) {
++            virMutexLock(&virNetDevTapCreateMutex);
++
++            if (virNetDevTapLastID < (int)id)
++                virNetDevTapLastID = id;
++
++            virMutexUnlock(&virNetDevTapCreateMutex);
++        }
++    }
++}
++
++
+ /**
+  * virNetDevTapGetName:
+  * @tapfd: a tun/tap file descriptor
+@@ -200,6 +240,55 @@ virNetDevProbeVnetHdr(int tapfd)
+ 
+ 
+ #ifdef TUNSETIFF
++/**
++ * virNetDevTapGenerateName:
++ * @ifname: pointer to pointer to string containing template
++ *
++ * generate a new (currently unused) name for a new tap device based
++ * on the templace string in @ifname - replace %d with
++ * ++virNetDevTapLastID, and keep trying new values until one is found
++ * that doesn't already exist, or we've tried 10000 different
++ * names. Once a usable name is found, replace the template with the
++ * actual name.
++ *
++ * Returns 0 on success, -1 on failure.
++ */
++static int
++virNetDevTapGenerateName(char **ifname)
++{
++    int id;
++    double maxIDd = pow(10, IFNAMSIZ - 1 - strlen(VIR_NET_GENERATED_TAP_PREFIX));
++    int maxID = INT_MAX;
++    int attempts = 0;
++
++    if (maxIDd <= (double)INT_MAX)
++        maxID = (int)maxIDd;
++
++    do {
++        g_autofree char *try = NULL;
++
++        id = ++virNetDevTapLastID;
++
++        /* reset before overflow */
++        if (virNetDevTapLastID >= maxID)
++            virNetDevTapLastID = -1;
++
++        try = g_strdup_printf(*ifname, id);
++
++        if (!virNetDevExists(try)) {
++            g_free(*ifname);
++            *ifname = g_steal_pointer(&try);
++            return 0;
++        }
++    } while (++attempts < 10000);
++
++    virReportError(VIR_ERR_INTERNAL_ERROR,
++                   _("no unused %s names available"),
++                   VIR_NET_GENERATED_TAP_PREFIX);
++    return -1;
++}
++
++
+ /**
+  * virNetDevTapCreate:
+  * @ifname: the interface name
+@@ -226,10 +315,22 @@ int virNetDevTapCreate(char **ifname,
+                        size_t tapfdSize,
+                        unsigned int flags)
+ {
+-    size_t i;
++    size_t i = 0;
+     struct ifreq ifr;
+     int ret = -1;
+-    int fd;
++    int fd = 0;
++
++    virMutexLock(&virNetDevTapCreateMutex);
++
++    /* if ifname is "vnet%d", then auto-generate a name for the new
++     * device (the kernel could do this for us, but has a bad habit of
++     * immediately re-using names that have just been released, which
++     * can lead to race conditions).
++     */
++    if (STREQ(*ifname, VIR_NET_GENERATED_TAP_PREFIX "%d") &&
++        virNetDevTapGenerateName(ifname) < 0) {
++        goto cleanup;
++    }
+ 
+     if (!tunpath)
+         tunpath = "/dev/net/tun";
+@@ -295,9 +396,11 @@ int virNetDevTapCreate(char **ifname,
+         tapfd[i] = fd;
+     }
+ 
++    VIR_INFO("created device: '%s'", *ifname);
+     ret = 0;
+ 
+  cleanup:
++    virMutexUnlock(&virNetDevTapCreateMutex);
+     if (ret < 0) {
+         VIR_FORCE_CLOSE(fd);
+         while (i--)
+@@ -347,6 +450,7 @@ int virNetDevTapDelete(const char *ifname,
+         goto cleanup;
+     }
+ 
++    VIR_INFO("delete device: '%s'", ifname);
+     ret = 0;
+ 
+  cleanup:
+diff --git a/src/util/virnetdevtap.h b/src/util/virnetdevtap.h
+index cae8e61861..2994c9ca71 100644
+--- a/src/util/virnetdevtap.h
++++ b/src/util/virnetdevtap.h
+@@ -29,6 +29,10 @@
+ # define VIR_NETDEV_TAP_REQUIRE_MANUAL_CLEANUP 1
+ #endif
+ 
++void
++virNetDevTapReserveName(const char *name)
++    ATTRIBUTE_NONNULL(1);
++
+ int virNetDevTapCreate(char **ifname,
+                        const char *tunpath,
+                        int *tapfd,
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-util-avoid-manual-VIR_FREE-of-a-g_autofree-pointer-in-virPCIGetName.patch b/SOURCES/libvirt-util-avoid-manual-VIR_FREE-of-a-g_autofree-pointer-in-virPCIGetName.patch
new file mode 100644
index 0000000..bb987c0
--- /dev/null
+++ b/SOURCES/libvirt-util-avoid-manual-VIR_FREE-of-a-g_autofree-pointer-in-virPCIGetName.patch
@@ -0,0 +1,52 @@
+From 4eed301c16a93fdcc6867823a88406e9578c1da7 Mon Sep 17 00:00:00 2001
+Message-Id: <4eed301c16a93fdcc6867823a88406e9578c1da7@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Thu, 28 Jan 2021 23:17:28 -0500
+Subject: [PATCH] util: avoid manual VIR_FREE of a g_autofree pointer in
+ virPCIGetName()
+
+thisPhysPortID is only used inside a conditional, so reduce its scope
+to just the body of that conditional, which will eliminate the need
+for the undesirable manual VIR_FREE().
+
+https://bugzilla.redhat.com/1918708
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+Reviewed-by: Peter Krempa <pkrempa@redhat.com>
+(cherry picked from commit fefd478644a2ad2951491552081cd53b6ecd4223)
+Message-Id: <20210129041729.1076345-3-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virpci.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/util/virpci.c b/src/util/virpci.c
+index 0b1222373e..00377eed31 100644
+--- a/src/util/virpci.c
++++ b/src/util/virpci.c
+@@ -2440,7 +2440,6 @@ virPCIGetNetName(const char *device_link_sysfs_path,
+ {
+     g_autofree char *pcidev_sysfs_net_path = NULL;
+     g_autofree char *firstEntryName = NULL;
+-    g_autofree char *thisPhysPortID = NULL;
+     int ret = -1;
+     DIR *dir = NULL;
+     struct dirent *entry = NULL;
+@@ -2465,12 +2464,13 @@ virPCIGetNetName(const char *device_link_sysfs_path,
+          * physportID of this netdev. If not, look for entry[idx].
+          */
+         if (physPortID) {
++            g_autofree char *thisPhysPortID = NULL;
++
+             if (virNetDevGetPhysPortID(entry->d_name, &thisPhysPortID) < 0)
+                 goto cleanup;
+ 
+             /* if this one doesn't match, keep looking */
+             if (STRNEQ_NULLABLE(physPortID, thisPhysPortID)) {
+-                VIR_FREE(thisPhysPortID);
+                 /* save the first entry we find to use as a failsafe
+                  * in case we don't match the phys_port_id. This is
+                  * needed because some NIC drivers (e.g. i40e)
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-util-call-iptables-directly-rather-than-via-firewalld.patch b/SOURCES/libvirt-util-call-iptables-directly-rather-than-via-firewalld.patch
new file mode 100644
index 0000000..3ec098c
--- /dev/null
+++ b/SOURCES/libvirt-util-call-iptables-directly-rather-than-via-firewalld.patch
@@ -0,0 +1,228 @@
+From 4d8a10886f4dffd08fcf6a93694e12f76a2afd66 Mon Sep 17 00:00:00 2001
+Message-Id: <4d8a10886f4dffd08fcf6a93694e12f76a2afd66@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Fri, 15 Jan 2021 22:51:51 -0500
+Subject: [PATCH] util: call iptables directly rather than via firewalld
+
+When libvirt added support for firewalld, we were unable to use
+firewalld's higher level rules, because they weren't detailed enough
+and could not be applied to the iptables FORWARD or OUTPUT chains
+(only to the INPUT chain). Instead we changed our code so that rather
+than running the iptables/ip6tables/ebtables binaries ourselves, we
+would send these commands to firewalld as "passthrough commands", and
+firewalld would run the appropriate program on our behalf.
+
+This was done under the assumption that firewalld was somehow tracking
+all these rules, and that this tracking was benefitting proper
+operation of firewalld and the system in general.
+
+Several years later this came up in a discussion on IRC, and we
+learned from the firewalld developers that, in fact, adding iptables
+and ebtables rules with firewalld's passthrough commands actually has
+*no* advantage; firewalld doesn't keep track of these rules in any
+way, and doesn't use them to tailor the construction of its own rules.
+
+Meanwhile, users have been complaining for some time that whenever
+firewalld is restarted on a system with libvirt virtual networks
+and/or nwfilter rules active, the system logs would be flooded with
+warning messages whining that [lots of different rules] could not be
+deleted because they didn't exist. For example:
+
+firewalld[3536040]: WARNING: COMMAND_FAILED:
+  '/usr/sbin/iptables -w10 -w --table filter --delete LIBVIRT_OUT
+  --out-interface virbr4 --protocol udp --destination-port 68
+  --jump ACCEPT' failed: iptables: Bad rule
+  (does a matching rule exist in that chain?).
+
+See:
+
+  https://bugzilla.redhat.com/1607929 (RHEL8)
+  https://bugzilla.redhat.com/1790837 (RHEL8-AV)
+
+for many more examples and a discussion)
+
+Note that these messages are created by iptables, but are logged by
+firewalld - when an iptables/ebtables command fails, firewalld grabs
+whatever is in stderr of the program, and spits it out to the system
+log as a warning. We've requested that firewalld not do this (and
+instead leave it up to the calling application to do the appropriate
+logging), but this request has been respectfully denied.
+
+But combining the two problems above ( 1) firewalld doesn't do
+anything useful when you use it as a proxy to add/remove iptables
+rules, 2) firewalld often insists on logging lots of
+annoying/misleading/useless "error" messages when you use it as a
+proxy to remove iptables rules that don't already exist), leads to a
+solution - simply stop using firewalld to add and remove iptables
+rules. Instead, exec iptables/ip6tables/ebtables directly in the same
+way we do when firewalld isn't active.
+
+We still need to keep track of whether or not firewalld is active, as
+there are some things that must be done, e.g. we need to add some
+actual firewalld rules in the firewalld "libvirt" zone, and we need to
+take notice when firewalld restarts, so that we can reload all our
+rules.
+
+This patch doesn't remove the infrastructure that allows having
+different firewall backends that perform their functions in different
+ways, as that will very possibly come in handy in the future when we
+want to have an nftables direct backend, and possibly a "pure"
+firewalld backend (now that firewalld supports more complex rules, and
+can add those rules to the FORWARD and OUTPUT chains). Instead, it
+just changes the action when the selected backend is "firewalld" so
+that it adds rules directly rather than through firewalld, while
+leaving as much of the existing code intact as possible.
+
+In order for tests to still pass, virfirewalltest also had to be
+modified to behave in a different way (i.e. by capturing the generated
+commandline as it does for the DIRECT backend, rather than capturing
+dbus messages using a mocked dbus API).
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit b19863640d10b47b7c4a7cbadb21f196d61d96a2)
+Message-Id: <20210116035151.1066734-9-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virfirewall.c  | 13 +++++++++++--
+ tests/virfirewalltest.c | 30 ++++++++++++++++++++----------
+ 2 files changed, 31 insertions(+), 12 deletions(-)
+
+diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c
+index 66d20d3f17..2ea821ec17 100644
+--- a/src/util/virfirewall.c
++++ b/src/util/virfirewall.c
+@@ -644,7 +644,7 @@ virFirewallApplyRuleDirect(virFirewallRulePtr rule,
+ }
+ 
+ 
+-static int
++static int G_GNUC_UNUSED
+ virFirewallApplyRuleFirewallD(virFirewallRulePtr rule,
+                               bool ignoreErrors,
+                               char **output)
+@@ -702,7 +702,16 @@ virFirewallApplyRule(virFirewallPtr firewall,
+             return -1;
+         break;
+     case VIR_FIREWALL_BACKEND_FIREWALLD:
+-        if (virFirewallApplyRuleFirewallD(rule, ignoreErrors, &output) < 0)
++        /* Since we are using raw iptables rules, there is no
++         * advantage to going through firewalld, so instead just add
++         * them directly rather that via dbus calls to firewalld. This
++         * has the useful side effect of eliminating extra unwanted
++         * warning messages in the system logs when trying to delete
++         * rules that don't exist (which is something that happens
++         * often when libvirtd is started, and *always* when firewalld
++         * is restarted)
++         */
++        if (virFirewallApplyRuleDirect(rule, ignoreErrors, &output) < 0)
+             return -1;
+         break;
+ 
+diff --git a/tests/virfirewalltest.c b/tests/virfirewalltest.c
+index 40e7f4f00b..1036353579 100644
+--- a/tests/virfirewalltest.c
++++ b/tests/virfirewalltest.c
+@@ -214,7 +214,8 @@ testFirewallSingleGroup(const void *opaque)
+     if (virFirewallSetBackend(data->tryBackend) < 0)
+         goto cleanup;
+ 
+-    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT)
++    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT ||
++        data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD)
+         virCommandSetDryRun(&cmdbuf, NULL, NULL);
+     else
+         fwBuf = &cmdbuf;
+@@ -271,7 +272,8 @@ testFirewallRemoveRule(const void *opaque)
+     if (virFirewallSetBackend(data->tryBackend) < 0)
+         goto cleanup;
+ 
+-    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT)
++    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT ||
++        data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD)
+         virCommandSetDryRun(&cmdbuf, NULL, NULL);
+     else
+         fwBuf = &cmdbuf;
+@@ -335,7 +337,8 @@ testFirewallManyGroups(const void *opaque G_GNUC_UNUSED)
+     if (virFirewallSetBackend(data->tryBackend) < 0)
+         goto cleanup;
+ 
+-    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT)
++    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT ||
++        data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD)
+         virCommandSetDryRun(&cmdbuf, NULL, NULL);
+     else
+         fwBuf = &cmdbuf;
+@@ -426,7 +429,8 @@ testFirewallIgnoreFailGroup(const void *opaque G_GNUC_UNUSED)
+     if (virFirewallSetBackend(data->tryBackend) < 0)
+         goto cleanup;
+ 
+-    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) {
++    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT ||
++        data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) {
+         virCommandSetDryRun(&cmdbuf, testFirewallRollbackHook, NULL);
+     } else {
+         fwBuf = &cmdbuf;
+@@ -498,7 +502,8 @@ testFirewallIgnoreFailRule(const void *opaque G_GNUC_UNUSED)
+     if (virFirewallSetBackend(data->tryBackend) < 0)
+         goto cleanup;
+ 
+-    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) {
++    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT ||
++        data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) {
+         virCommandSetDryRun(&cmdbuf, testFirewallRollbackHook, NULL);
+     } else {
+         fwBuf = &cmdbuf;
+@@ -567,7 +572,8 @@ testFirewallNoRollback(const void *opaque G_GNUC_UNUSED)
+     if (virFirewallSetBackend(data->tryBackend) < 0)
+         goto cleanup;
+ 
+-    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) {
++    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT ||
++        data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) {
+         virCommandSetDryRun(&cmdbuf, testFirewallRollbackHook, NULL);
+     } else {
+         fwBuf = &cmdbuf;
+@@ -634,7 +640,8 @@ testFirewallSingleRollback(const void *opaque G_GNUC_UNUSED)
+     if (virFirewallSetBackend(data->tryBackend) < 0)
+         goto cleanup;
+ 
+-    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) {
++    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT ||
++        data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) {
+         virCommandSetDryRun(&cmdbuf, testFirewallRollbackHook, NULL);
+     } else {
+         fwError = true;
+@@ -717,7 +724,8 @@ testFirewallManyRollback(const void *opaque G_GNUC_UNUSED)
+     if (virFirewallSetBackend(data->tryBackend) < 0)
+         goto cleanup;
+ 
+-    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) {
++    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT ||
++        data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) {
+         virCommandSetDryRun(&cmdbuf, testFirewallRollbackHook, NULL);
+     } else {
+         fwBuf = &cmdbuf;
+@@ -808,7 +816,8 @@ testFirewallChainedRollback(const void *opaque G_GNUC_UNUSED)
+     if (virFirewallSetBackend(data->tryBackend) < 0)
+         goto cleanup;
+ 
+-    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) {
++    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT ||
++        data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) {
+         virCommandSetDryRun(&cmdbuf, testFirewallRollbackHook, NULL);
+     } else {
+         fwBuf = &cmdbuf;
+@@ -1007,7 +1016,8 @@ testFirewallQuery(const void *opaque G_GNUC_UNUSED)
+     if (virFirewallSetBackend(data->tryBackend) < 0)
+         goto cleanup;
+ 
+-    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) {
++    if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT ||
++        data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) {
+         virCommandSetDryRun(&cmdbuf, testFirewallQueryHook, NULL);
+     } else {
+         fwBuf = &cmdbuf;
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-util-fix-typo-in-VIR_MOCK_WRAP_RET_ARGS.patch b/SOURCES/libvirt-util-fix-typo-in-VIR_MOCK_WRAP_RET_ARGS.patch
new file mode 100644
index 0000000..6a8ab2d
--- /dev/null
+++ b/SOURCES/libvirt-util-fix-typo-in-VIR_MOCK_WRAP_RET_ARGS.patch
@@ -0,0 +1,39 @@
+From 15b1f63574db2100d433d283a975928f83bb0ecb Mon Sep 17 00:00:00 2001
+Message-Id: <15b1f63574db2100d433d283a975928f83bb0ecb@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Fri, 15 Jan 2021 22:51:44 -0500
+Subject: [PATCH] util: fix typo in VIR_MOCK_WRAP_RET_ARGS()
+
+When virfirewalltest.c was first written in commit 3a0ca7de51 (March
+2013), a conditional accidentally tested for "ipv4" instead of
+"ipv6". Since the file ended up only testing ipv4 rules, this has
+never made any difference in practice, but I'm making some other
+changes in this file and just couldn't let it stand :-)
+
+https://bugzilla.redhat.com/1607929
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 28a3deddddfe102b37f2e373bf4581c2ce8d2050)
+Message-Id: <20210116035151.1066734-2-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ tests/virfirewalltest.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tests/virfirewalltest.c b/tests/virfirewalltest.c
+index c4827918c3..8aba127610 100644
+--- a/tests/virfirewalltest.c
++++ b/tests/virfirewalltest.c
+@@ -129,7 +129,7 @@ VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block,
+         if (fwBuf) {
+             if (STREQ(type, "ipv4"))
+                 virBufferAddLit(fwBuf, IPTABLES_PATH);
+-            else if (STREQ(type, "ipv4"))
++            else if (STREQ(type, "ipv6"))
+                 virBufferAddLit(fwBuf, IP6TABLES_PATH);
+             else
+                 virBufferAddLit(fwBuf, EBTABLES_PATH);
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-util-replace-macvtap-name-reservation-bitmap-with-a-simple-counter.patch b/SOURCES/libvirt-util-replace-macvtap-name-reservation-bitmap-with-a-simple-counter.patch
new file mode 100644
index 0000000..34969d8
--- /dev/null
+++ b/SOURCES/libvirt-util-replace-macvtap-name-reservation-bitmap-with-a-simple-counter.patch
@@ -0,0 +1,736 @@
+From 4238e5f0783c63802de79bc5ed2a1f49673ef2a3 Mon Sep 17 00:00:00 2001
+Message-Id: <4238e5f0783c63802de79bc5ed2a1f49673ef2a3@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Sat, 12 Dec 2020 22:04:51 -0500
+Subject: [PATCH] util: replace macvtap name reservation bitmap with a simple
+ counter
+
+There have been some reports that, due to libvirt always trying to
+assign the lowest numbered macvtap / tap device name possible, a new
+guest would sometimes be started using the same tap device name as
+previously used by another guest that is in the process of being
+destroyed *as the new guest is starting.
+
+In some cases this has led to, for example, the old guest's
+qemuProcessStop() code deleting a port from an OVS switch that had
+just been re-added by the new guest (because the port name is based on
+only the device name using the port). Similar problems can happen (and
+I believe have) with nwfilter rules and bandwidth rules (which are
+both instantiated based on the name of the tap device).
+
+A couple patches have been previously proposed to change the ordering
+of startup and shutdown processing, or to put a mutex around
+everything related to the tap/macvtap device name usage, but in the
+end no matter what you do there will still be possible holes, because
+the device could be deleted outside libvirt's control (for example,
+regular tap devices are automatically deleted when the qemu process
+terminates, and that isn't always initiated by libvirt but could
+instead happen completely asynchronously - libvirt then has no control
+over the ordering of shutdown operations, and no opportunity to
+protect it with a mutex.)
+
+But this only happens if a new device is created at the same time as
+one is being deleted. We can effectively eliminate the chance of this
+happening if we end the practice of always looking for the lowest
+numbered available device name, and instead just keep an integer that
+is incremented each time we need a new device name. At some point it
+will need to wrap back around to 0 (in order to avoid the IFNAMSIZ 15
+character limit if nothing else), and we can't guarantee that the new
+name really will be the *least* recently used name, but "math"
+suggests that it will be *much* less common that we'll try to re-use
+the *most* recently used name.
+
+This patch implements such a counter for macvtap/macvlan, replacing
+the existing, and much more complicated, "ID reservation" system. The
+counter is set according to whatever macvtap/macvlan devices are
+already in use by guests when libvirtd is started, incremented each
+time a new device name is needed, and wraps back to 0 when either
+INT_MAX is reached, or when the resulting device name would be longer
+than IFNAMSIZ-1 characters (which actually is what happens when the
+template for the device name is "maccvtap%d"). The result is that no
+macvtap name will be re-used until the host has created (and possibly
+destroyed) 99,999,999 devices.
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit d7f38beb2ee072f1f19bb91fbafc9182ce9b069e)
+
+https://bugzilla.redhat.com/1874304
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20201213030453.48851-2-laine@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/libvirt_private.syms    |   1 -
+ src/libxl/libxl_driver.c    |   2 +-
+ src/lxc/lxc_process.c       |   2 +-
+ src/qemu/qemu_process.c     |   2 +-
+ src/util/virnetdevmacvlan.c | 403 +++++++++++++-----------------------
+ src/util/virnetdevmacvlan.h |   6 +-
+ 6 files changed, 145 insertions(+), 271 deletions(-)
+
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index fdd104cd25..1c66c40f86 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -2604,7 +2604,6 @@ virNetDevMacVLanDelete;
+ virNetDevMacVLanDeleteWithVPortProfile;
+ virNetDevMacVLanIsMacvtap;
+ virNetDevMacVLanModeTypeFromString;
+-virNetDevMacVLanReleaseName;
+ virNetDevMacVLanReserveName;
+ virNetDevMacVLanRestartWithVPortProfile;
+ virNetDevMacVLanTapOpen;
+diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
+index 1449795494..9269e9b475 100644
+--- a/src/libxl/libxl_driver.c
++++ b/src/libxl/libxl_driver.c
+@@ -367,7 +367,7 @@ libxlReconnectNotifyNets(virDomainDefPtr def)
+          * impolite.
+          */
+         if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT)
+-           ignore_value(virNetDevMacVLanReserveName(net->ifname, false));
++            virNetDevMacVLanReserveName(net->ifname);
+ 
+         if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+             if (!conn && !(conn = virGetConnectNetwork()))
+diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
+index 0a9ccdf9ec..114c40b0ea 100644
+--- a/src/lxc/lxc_process.c
++++ b/src/lxc/lxc_process.c
+@@ -1638,7 +1638,7 @@ virLXCProcessReconnectNotifyNets(virDomainDefPtr def)
+          * impolite.
+          */
+         if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT)
+-           ignore_value(virNetDevMacVLanReserveName(net->ifname, false));
++            virNetDevMacVLanReserveName(net->ifname);
+ 
+         if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+             if (!conn && !(conn = virGetConnectNetwork()))
+diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
+index 95c0315e53..b49a463c02 100644
+--- a/src/qemu/qemu_process.c
++++ b/src/qemu/qemu_process.c
+@@ -3288,7 +3288,7 @@ qemuProcessNotifyNets(virDomainDefPtr def)
+          * impolite.
+          */
+         if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT)
+-           ignore_value(virNetDevMacVLanReserveName(net->ifname, false));
++            virNetDevMacVLanReserveName(net->ifname);
+ 
+         if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+             if (!conn && !(conn = virGetConnectNetwork()))
+diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c
+index 3ca568fb44..7046cbb04e 100644
+--- a/src/util/virnetdevmacvlan.c
++++ b/src/util/virnetdevmacvlan.c
+@@ -47,6 +47,7 @@ VIR_ENUM_IMPL(virNetDevMacVLanMode,
+ 
+ # include <net/if.h>
+ # include <linux/if_tun.h>
++# include <math.h>
+ 
+ /* Older kernels lacked this enum value.  */
+ # if !HAVE_DECL_MACVLAN_MODE_PASSTHRU
+@@ -70,211 +71,121 @@ VIR_LOG_INIT("util.netdevmacvlan");
+     ((flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? \
+      VIR_NET_GENERATED_MACVTAP_PREFIX : VIR_NET_GENERATED_MACVLAN_PREFIX)
+ 
+-# define MACVLAN_MAX_ID 8191
+ 
+ virMutex virNetDevMacVLanCreateMutex = VIR_MUTEX_INITIALIZER;
+-virBitmapPtr macvtapIDs = NULL;
+-virBitmapPtr macvlanIDs = NULL;
+-
+-static int
+-virNetDevMacVLanOnceInit(void)
+-{
+-    if (!macvtapIDs &&
+-        !(macvtapIDs = virBitmapNew(MACVLAN_MAX_ID + 1)))
+-        return -1;
+-    if (!macvlanIDs &&
+-        !(macvlanIDs = virBitmapNew(MACVLAN_MAX_ID + 1)))
+-        return -1;
+-    return 0;
+-}
+-
+-VIR_ONCE_GLOBAL_INIT(virNetDevMacVLan);
++static int virNetDevMacVTapLastID = -1;
++static int virNetDevMacVLanLastID = -1;
+ 
+ 
+-/**
+- * virNetDevMacVLanReserveID:
+- *
+- *  @id: id 0 - MACVLAN_MAX_ID+1 to reserve (or -1 for "first free")
+- *  @flags: set VIR_NETDEV_MACVLAN_CREATE_WITH_TAP for macvtapN else macvlanN
+- *  @quietFail: don't log an error if this name is already in-use
+- *  @nextFree: reserve the next free ID *after* @id rather than @id itself
+- *
+- *  Reserve the indicated ID in the appropriate bitmap, or find the
+- *  first free ID if @id is -1.
+- *
+- *  Returns newly reserved ID# on success, or -1 to indicate failure.
+- */
+-static int
+-virNetDevMacVLanReserveID(int id, unsigned int flags,
+-                          bool quietFail, bool nextFree)
++static void
++virNetDevMacVLanReserveNameInternal(const char *name)
+ {
+-    virBitmapPtr bitmap;
+-
+-    if (virNetDevMacVLanInitialize() < 0)
+-       return -1;
+-
+-    bitmap = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
+-        macvtapIDs :  macvlanIDs;
++    unsigned int id;
++    const char *idstr = NULL;
++    int *lastID = NULL;
++    int len;
+ 
+-    if (id > MACVLAN_MAX_ID) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-                       _("can't use name %s%d - out of range 0-%d"),
+-                       VIR_NET_GENERATED_PREFIX, id, MACVLAN_MAX_ID);
+-        return -1;
++    if (STRPREFIX(name, VIR_NET_GENERATED_MACVTAP_PREFIX)) {
++        lastID = &virNetDevMacVTapLastID;
++        len = strlen(VIR_NET_GENERATED_MACVTAP_PREFIX);
++    } else if (STRPREFIX(name, VIR_NET_GENERATED_MACVLAN_PREFIX)) {
++        lastID = &virNetDevMacVTapLastID;
++        len = strlen(VIR_NET_GENERATED_MACVLAN_PREFIX);
++    } else {
++        return;
+     }
+ 
+-    if ((id < 0 || nextFree) &&
+-        (id = virBitmapNextClearBit(bitmap, id)) < 0) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-                       _("no unused %s names available"),
+-                       VIR_NET_GENERATED_PREFIX);
+-        return -1;
+-    }
++    VIR_INFO("marking device in use: '%s'", name);
+ 
+-    if (virBitmapIsBitSet(bitmap, id)) {
+-        if (quietFail) {
+-            VIR_INFO("couldn't reserve name %s%d - already in use",
+-                     VIR_NET_GENERATED_PREFIX, id);
+-        } else {
+-            virReportError(VIR_ERR_INTERNAL_ERROR,
+-                           _("couldn't reserve name %s%d - already in use"),
+-                           VIR_NET_GENERATED_PREFIX, id);
+-        }
+-        return -1;
+-    }
++    idstr = name + len;
+ 
+-    if (virBitmapSetBit(bitmap, id) < 0) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-                       _("couldn't mark %s%d as used"),
+-                       VIR_NET_GENERATED_PREFIX, id);
+-        return -1;
++    if (virStrToLong_ui(idstr, NULL, 10, &id) >= 0) {
++        if (*lastID < (int)id)
++            *lastID = id;
+     }
+-
+-    VIR_INFO("reserving device %s%d", VIR_NET_GENERATED_PREFIX, id);
+-    return id;
+ }
+ 
+ 
+ /**
+- * virNetDevMacVLanReleaseID:
+- *  @id: id 0 - MACVLAN_MAX_ID+1 to release
++ * virNetDevMacVLanReserveName:
++ * @name: name of an existing macvtap/macvlan device
+  *
+- *  Returns 0 for success or -1 for failure.
++ * Set the value of virNetDevMacV(Lan|Tap)LastID to assure that any
++ * new device created with an autogenerated name will use a number
++ * higher than the number in the given device name.
++ *
++ * Returns nothing.
+  */
+-static int
+-virNetDevMacVLanReleaseID(int id, unsigned int flags)
++void
++virNetDevMacVLanReserveName(const char *name)
+ {
+-    virBitmapPtr bitmap;
+-
+-    if (virNetDevMacVLanInitialize() < 0)
+-        return 0;
+-
+-    bitmap = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
+-        macvtapIDs :  macvlanIDs;
+-
+-    if (id > MACVLAN_MAX_ID) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-                       _("can't free name %s%d - out of range 0-%d"),
+-                       VIR_NET_GENERATED_PREFIX, id, MACVLAN_MAX_ID);
+-        return -1;
+-    }
+-
+-    if (id < 0)
+-        return 0;
+-
+-    VIR_INFO("releasing %sdevice %s%d",
+-             virBitmapIsBitSet(bitmap, id) ? "" : "unreserved",
+-             VIR_NET_GENERATED_PREFIX, id);
+-
+-    if (virBitmapClearBit(bitmap, id) < 0) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-                       _("couldn't mark %s%d as unused"),
+-                       VIR_NET_GENERATED_PREFIX, id);
+-        return -1;
+-    }
+-    return 0;
++    virMutexLock(&virNetDevMacVLanCreateMutex);
++    virNetDevMacVLanReserveNameInternal(name);
++    virMutexUnlock(&virNetDevMacVLanCreateMutex);
+ }
+ 
+ 
+ /**
+- * virNetDevMacVLanReserveName:
+- *
+- *  @name: already-known name of device
+- *  @quietFail: don't log an error if this name is already in-use
++ * virNetDevMacVLanGenerateName:
++ * @ifname: pointer to pointer to string containing template
++ * @lastID: counter to add to the template to form the name
+  *
+- *  Extract the device type and id from a macvtap/macvlan device name
+- *  and mark the appropriate position as in-use in the appropriate
+- *  bitmap.
++ * generate a new (currently unused) name for a new macvtap/macvlan
++ * device based on the template string in @ifname - replace %d with
++ * ++(*counter), and keep trying new values until one is found
++ * that doesn't already exist, or we've tried 10000 different
++ * names. Once a usable name is found, replace the template with the
++ * actual name.
+  *
+- *  Returns reserved ID# on success, -1 on failure, -2 if the name
+- *  doesn't fit the auto-pattern (so not reserveable).
++ * Returns 0 on success, -1 on failure.
+  */
+-int
+-virNetDevMacVLanReserveName(const char *name, bool quietFail)
++static int
++virNetDevMacVLanGenerateName(char **ifname, unsigned int flags)
+ {
+-    unsigned int id;
+-    unsigned int flags = 0;
+-    const char *idstr = NULL;
++    const char *prefix;
++    const char *iftemplate;
++    int *lastID;
++    int id;
++    double maxIDd;
++    int maxID = INT_MAX;
++    int attempts = 0;
+ 
+-    if (virNetDevMacVLanInitialize() < 0)
+-       return -1;
+-
+-    if (STRPREFIX(name, VIR_NET_GENERATED_MACVTAP_PREFIX)) {
+-        idstr = name + strlen(VIR_NET_GENERATED_MACVTAP_PREFIX);
+-        flags |= VIR_NETDEV_MACVLAN_CREATE_WITH_TAP;
+-    } else if (STRPREFIX(name, VIR_NET_GENERATED_MACVLAN_PREFIX)) {
+-        idstr = name + strlen(VIR_NET_GENERATED_MACVLAN_PREFIX);
++    if (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) {
++        prefix = VIR_NET_GENERATED_MACVTAP_PREFIX;
++        iftemplate = VIR_NET_GENERATED_MACVTAP_PREFIX "%d";
++        lastID = &virNetDevMacVTapLastID;
+     } else {
+-        return -2;
++        prefix = VIR_NET_GENERATED_MACVLAN_PREFIX;
++        iftemplate = VIR_NET_GENERATED_MACVLAN_PREFIX "%d";
++        lastID = &virNetDevMacVLanLastID;
+     }
+ 
+-    if (virStrToLong_ui(idstr, NULL, 10, &id) < 0) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-                       _("couldn't get id value from macvtap device name %s"),
+-                       name);
+-        return -1;
+-    }
+-    return virNetDevMacVLanReserveID(id, flags, quietFail, false);
+-}
++    maxIDd = pow(10, IFNAMSIZ - 1 - strlen(prefix));
++    if (maxIDd <= (double)INT_MAX)
++        maxID = (int)maxIDd;
+ 
++    do {
++        g_autofree char *try = NULL;
+ 
+-/**
+- * virNetDevMacVLanReleaseName:
+- *
+- *  @name: already-known name of device
+- *
+- *  Extract the device type and id from a macvtap/macvlan device name
+- *  and mark the appropriate position as in-use in the appropriate
+- *  bitmap.
+- *
+- *  returns 0 on success, -1 on failure
+- */
+-int
+-virNetDevMacVLanReleaseName(const char *name)
+-{
+-    unsigned int id;
+-    unsigned int flags = 0;
+-    const char *idstr = NULL;
++        id = ++(*lastID);
+ 
+-    if (virNetDevMacVLanInitialize() < 0)
+-       return -1;
++        /* reset before overflow */
++        if (*lastID == maxID)
++            *lastID = -1;
+ 
+-    if (STRPREFIX(name, VIR_NET_GENERATED_MACVTAP_PREFIX)) {
+-        idstr = name + strlen(VIR_NET_GENERATED_MACVTAP_PREFIX);
+-        flags |= VIR_NETDEV_MACVLAN_CREATE_WITH_TAP;
+-    } else if (STRPREFIX(name, VIR_NET_GENERATED_MACVLAN_PREFIX)) {
+-        idstr = name + strlen(VIR_NET_GENERATED_MACVLAN_PREFIX);
+-    } else {
+-        return 0;
+-    }
++        try = g_strdup_printf(iftemplate, id);
+ 
+-    if (virStrToLong_ui(idstr, NULL, 10, &id) < 0) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-                       _("couldn't get id value from macvtap device name %s"),
+-                       name);
+-        return -1;
+-    }
+-    return virNetDevMacVLanReleaseID(id, flags);
++        if (!virNetDevExists(try)) {
++            g_free(*ifname);
++            *ifname = g_steal_pointer(&try);
++            return 0;
++        }
++    } while (++attempts < 10000);
++
++    virReportError(VIR_ERR_INTERNAL_ERROR,
++                   _("no unused %s names available"),
++                   *ifname);
++    return -1;
+ }
+ 
+ 
+@@ -321,8 +232,7 @@ virNetDevMacVLanCreate(const char *ifname,
+                        const char *type,
+                        const virMacAddr *macaddress,
+                        const char *srcdev,
+-                       uint32_t macvlan_mode,
+-                       int *retry)
++                       uint32_t macvlan_mode)
+ {
+     int error = 0;
+     int ifindex = 0;
+@@ -331,7 +241,6 @@ virNetDevMacVLanCreate(const char *ifname,
+         .mac = macaddress,
+     };
+ 
+-    *retry = 0;
+ 
+     if (virNetDevGetIndex(srcdev, &ifindex) < 0)
+         return -1;
+@@ -339,17 +248,15 @@ virNetDevMacVLanCreate(const char *ifname,
+     data.ifindex = &ifindex;
+     if (virNetlinkNewLink(ifname, type, &data, &error) < 0) {
+         char macstr[VIR_MAC_STRING_BUFLEN];
+-        if (error == -EEXIST)
+-            *retry = 1;
+-        else if (error < 0)
+-            virReportSystemError(-error,
+-                                 _("error creating %s interface %s@%s (%s)"),
+-                                 type, ifname, srcdev,
+-                                 virMacAddrFormat(macaddress, macstr));
+ 
++        virReportSystemError(-error,
++                             _("error creating %s interface %s@%s (%s)"),
++                             type, ifname, srcdev,
++                             virMacAddrFormat(macaddress, macstr));
+         return -1;
+     }
+ 
++    VIR_INFO("created device: '%s'", ifname);
+     return 0;
+ }
+ 
+@@ -364,6 +271,7 @@ virNetDevMacVLanCreate(const char *ifname,
+  */
+ int virNetDevMacVLanDelete(const char *ifname)
+ {
++    VIR_INFO("delete device: '%s'", ifname);
+     return virNetlinkDelLink(ifname, NULL);
+ }
+ 
+@@ -904,13 +812,8 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested,
+                                        unsigned int flags)
+ {
+     const char *type = VIR_NET_GENERATED_PREFIX;
+-    const char *pattern = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
+-        VIR_NET_GENERATED_MACVTAP_PATTERN : VIR_NET_GENERATED_MACVLAN_PATTERN;
+-    int reservedID = -1;
+-    char ifname[IFNAMSIZ];
+-    int retries, do_retry = 0;
++    g_autofree char *ifname = NULL;
+     uint32_t macvtapMode;
+-    const char *ifnameCreated = NULL;
+     int vf = -1;
+     bool vnet_hdr = flags & VIR_NETDEV_MACVLAN_VNET_HDR;
+ 
+@@ -945,6 +848,8 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested,
+            return -1;
+     }
+ 
++    virMutexLock(&virNetDevMacVLanCreateMutex);
++
+     if (ifnameRequested) {
+         int rc;
+         bool isAutoName
+@@ -952,97 +857,81 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested,
+                STRPREFIX(ifnameRequested, VIR_NET_GENERATED_MACVLAN_PREFIX));
+ 
+         VIR_INFO("Requested macvtap device name: %s", ifnameRequested);
+-        virMutexLock(&virNetDevMacVLanCreateMutex);
+ 
+         if ((rc = virNetDevExists(ifnameRequested)) < 0) {
+             virMutexUnlock(&virNetDevMacVLanCreateMutex);
+             return -1;
+         }
++
+         if (rc) {
+-            if (isAutoName)
+-                goto create_name;
+-            virReportSystemError(EEXIST,
+-                                 _("Unable to create %s device %s"),
+-                                 type, ifnameRequested);
+-            virMutexUnlock(&virNetDevMacVLanCreateMutex);
+-            return -1;
+-        }
+-        if (isAutoName &&
+-            (reservedID = virNetDevMacVLanReserveName(ifnameRequested, true)) < 0) {
+-            reservedID = -1;
+-            goto create_name;
+-        }
++            /* ifnameRequested is already being used */
+ 
+-        if (virNetDevMacVLanCreate(ifnameRequested, type, macaddress,
+-                                   linkdev, macvtapMode, &do_retry) < 0) {
+-            if (isAutoName) {
+-                virNetDevMacVLanReleaseName(ifnameRequested);
+-                reservedID = -1;
+-                goto create_name;
++            if (!isAutoName) {
++                virReportSystemError(EEXIST,
++                                     _("Unable to create device '%s'"),
++                                     ifnameRequested);
++                virMutexUnlock(&virNetDevMacVLanCreateMutex);
++                return -1;
++            }
++        } else {
++
++            /* ifnameRequested is available. try to open it */
++
++            virNetDevMacVLanReserveNameInternal(ifnameRequested);
++
++            if (virNetDevMacVLanCreate(ifnameRequested, type, macaddress,
++                                       linkdev, macvtapMode) == 0) {
++
++                /* virNetDevMacVLanCreate() was successful - use this name */
++                ifname = g_strdup(ifnameRequested);
++
++            } else if (!isAutoName) {
++                /* coudn't open ifnameRequested, but it wasn't an
++                 * autogenerated named, so there is nothing else to
++                 * try - fail and return.
++                 */
++                virMutexUnlock(&virNetDevMacVLanCreateMutex);
++                return -1;
+             }
+-            virMutexUnlock(&virNetDevMacVLanCreateMutex);
+-            return -1;
+         }
+-        /* virNetDevMacVLanCreate() was successful - use this name */
+-        ifnameCreated = ifnameRequested;
+- create_name:
+-        virMutexUnlock(&virNetDevMacVLanCreateMutex);
+     }
+ 
+-    retries = MACVLAN_MAX_ID;
+-    while (!ifnameCreated && retries) {
+-        virMutexLock(&virNetDevMacVLanCreateMutex);
+-        reservedID = virNetDevMacVLanReserveID(reservedID, flags, false, true);
+-        if (reservedID < 0) {
++    if (!ifname) {
++        /* ifnameRequested was NULL, or it was an already in use
++         * autogenerated name, so now we look for an unused
++         * autogenerated name.
++         */
++        if (virNetDevMacVLanGenerateName(&ifname, flags) < 0 ||
++            virNetDevMacVLanCreate(ifname, type, macaddress,
++                                   linkdev, macvtapMode) < 0) {
+             virMutexUnlock(&virNetDevMacVLanCreateMutex);
+             return -1;
+         }
+-        g_snprintf(ifname, sizeof(ifname), pattern, reservedID);
+-        if (virNetDevMacVLanCreate(ifname, type, macaddress, linkdev,
+-                                   macvtapMode, &do_retry) < 0) {
+-            virNetDevMacVLanReleaseID(reservedID, flags);
+-            virMutexUnlock(&virNetDevMacVLanCreateMutex);
+-            if (!do_retry)
+-                return -1;
+-            VIR_INFO("Device %s wasn't reserved but already existed, skipping",
+-                     ifname);
+-            retries--;
+-            continue;
+-        }
+-        ifnameCreated = ifname;
+-        virMutexUnlock(&virNetDevMacVLanCreateMutex);
+     }
+ 
+-    if (!ifnameCreated) {
+-        virReportError(VIR_ERR_INTERNAL_ERROR,
+-                       _("Too many unreserved %s devices in use"),
+-                       type);
+-        return -1;
+-    }
++    /* all done creating the device */
++    virMutexUnlock(&virNetDevMacVLanCreateMutex);
+ 
+-    if (virNetDevVPortProfileAssociate(ifnameCreated,
++    if (virNetDevVPortProfileAssociate(ifname,
+                                        virtPortProfile,
+                                        macaddress,
+                                        linkdev,
+                                        vf,
+-                                       vmuuid, vmOp, false) < 0)
++                                       vmuuid, vmOp, false) < 0) {
+         goto link_del_exit;
++    }
+ 
+     if (flags & VIR_NETDEV_MACVLAN_CREATE_IFUP) {
+-        if (virNetDevSetOnline(ifnameCreated, true) < 0)
++        if (virNetDevSetOnline(ifname, true) < 0)
+             goto disassociate_exit;
+     }
+ 
+     if (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) {
+-        if (virNetDevMacVLanTapOpen(ifnameCreated, tapfd, tapfdSize) < 0)
++        if (virNetDevMacVLanTapOpen(ifname, tapfd, tapfdSize) < 0)
+             goto disassociate_exit;
+ 
+         if (virNetDevMacVLanTapSetup(tapfd, tapfdSize, vnet_hdr) < 0)
+             goto disassociate_exit;
+-
+-        *ifnameResult = g_strdup(ifnameCreated);
+-    } else {
+-        *ifnameResult = g_strdup(ifnameCreated);
+     }
+ 
+     if (vmOp == VIR_NETDEV_VPORT_PROFILE_OP_CREATE ||
+@@ -1051,17 +940,18 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested,
+          * a saved image) - migration and libvirtd restart are handled
+          * elsewhere.
+          */
+-        if (virNetDevMacVLanVPortProfileRegisterCallback(ifnameCreated, macaddress,
++        if (virNetDevMacVLanVPortProfileRegisterCallback(ifname, macaddress,
+                                                          linkdev, vmuuid,
+                                                          virtPortProfile,
+                                                          vmOp) < 0)
+             goto disassociate_exit;
+     }
+ 
++    *ifnameResult = g_steal_pointer(&ifname);
+     return 0;
+ 
+  disassociate_exit:
+-    ignore_value(virNetDevVPortProfileDisassociate(ifnameCreated,
++    ignore_value(virNetDevVPortProfileDisassociate(ifname,
+                                                    virtPortProfile,
+                                                    macaddress,
+                                                    linkdev,
+@@ -1071,9 +961,7 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested,
+         VIR_FORCE_CLOSE(tapfd[tapfdSize]);
+ 
+  link_del_exit:
+-    ignore_value(virNetDevMacVLanDelete(ifnameCreated));
+-    virNetDevMacVLanReleaseName(ifnameCreated);
+-
++    ignore_value(virNetDevMacVLanDelete(ifname));
+     return -1;
+ }
+ 
+@@ -1107,7 +995,6 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname,
+             ret = -1;
+         if (virNetDevMacVLanDelete(ifname) < 0)
+             ret = -1;
+-        virNetDevMacVLanReleaseName(ifname);
+     }
+ 
+     if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) {
+@@ -1182,8 +1069,7 @@ int virNetDevMacVLanCreate(const char *ifname G_GNUC_UNUSED,
+                            const char *type G_GNUC_UNUSED,
+                            const virMacAddr *macaddress G_GNUC_UNUSED,
+                            const char *srcdev G_GNUC_UNUSED,
+-                           uint32_t macvlan_mode G_GNUC_UNUSED,
+-                           int *retry G_GNUC_UNUSED)
++                           uint32_t macvlan_mode G_GNUC_UNUSED)
+ {
+     virReportSystemError(ENOSYS, "%s",
+                          _("Cannot create macvlan devices on this platform"));
+@@ -1272,18 +1158,9 @@ int virNetDevMacVLanVPortProfileRegisterCallback(const char *ifname G_GNUC_UNUSE
+     return -1;
+ }
+ 
+-int virNetDevMacVLanReleaseName(const char *name G_GNUC_UNUSED)
++void virNetDevMacVLanReserveName(const char *name G_GNUC_UNUSED)
+ {
+     virReportSystemError(ENOSYS, "%s",
+                          _("Cannot create macvlan devices on this platform"));
+-    return -1;
+-}
+-
+-int virNetDevMacVLanReserveName(const char *name G_GNUC_UNUSED,
+-                                bool quietFail G_GNUC_UNUSED)
+-{
+-    virReportSystemError(ENOSYS, "%s",
+-                         _("Cannot create macvlan devices on this platform"));
+-    return -1;
+ }
+ #endif /* ! WITH_MACVTAP */
+diff --git a/src/util/virnetdevmacvlan.h b/src/util/virnetdevmacvlan.h
+index fc1bb018a2..48800a8fcf 100644
+--- a/src/util/virnetdevmacvlan.h
++++ b/src/util/virnetdevmacvlan.h
+@@ -54,8 +54,7 @@ typedef enum {
+ #define VIR_NET_GENERATED_MACVTAP_PREFIX "macvtap"
+ #define VIR_NET_GENERATED_MACVLAN_PREFIX "macvlan"
+ 
+-int virNetDevMacVLanReserveName(const char *name, bool quietfail);
+-int virNetDevMacVLanReleaseName(const char *name);
++void virNetDevMacVLanReserveName(const char *name);
+ 
+ bool virNetDevMacVLanIsMacvtap(const char *ifname)
+    ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT G_GNUC_NO_INLINE;
+@@ -64,8 +63,7 @@ int virNetDevMacVLanCreate(const char *ifname,
+                            const char *type,
+                            const virMacAddr *macaddress,
+                            const char *srcdev,
+-                           uint32_t macvlan_mode,
+-                           int *retry)
++                           uint32_t macvlan_mode)
+     ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4)
+     G_GNUC_WARN_UNUSED_RESULT;
+ 
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-util-synchronize-with-firewalld-before-we-start-calling-iptables-directly.patch b/SOURCES/libvirt-util-synchronize-with-firewalld-before-we-start-calling-iptables-directly.patch
new file mode 100644
index 0000000..63ca58b
--- /dev/null
+++ b/SOURCES/libvirt-util-synchronize-with-firewalld-before-we-start-calling-iptables-directly.patch
@@ -0,0 +1,152 @@
+From dc8cf11686c075166a3029e974a6caeefe521d75 Mon Sep 17 00:00:00 2001
+Message-Id: <dc8cf11686c075166a3029e974a6caeefe521d75@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Fri, 15 Jan 2021 22:51:50 -0500
+Subject: [PATCH] util: synchronize with firewalld before we start calling
+ iptables directly
+
+When it is starting up, firewalld will delete all existing iptables
+rules and chains before adding its own rules. If libvirtd were to try
+to directly add iptables rules during the time before firewalld has
+finished initializing, firewalld would end up deleting the rules that
+libvirtd has just added.
+
+Currently this isn't a problem, since libvirtd only adds iptables
+rules via the firewalld "passthrough command" API, and so firewalld is
+able to properly serialize everything. However, we will soon be
+changing libvirtd to add its iptables and ebtables rules by directly
+calling iptables/ebtables rather than via firewalld, thus removing the
+serialization of libvirtd adding rules vs. firewalld deleting rules.
+
+This will especially apparent (if we don't fix it in advance, as this
+patch does) when libvirtd is responding to the dbus NameOwnerChanged
+event, which is used to learn when firewalld has been restarted. In
+that case, dbus sends the event before firewalld has been able to
+complete its initialization, so when libvirt responds to the event by
+adding back its iptables rules (with direct calls to
+/usr/bin/iptables), some of those rules are added before firewalld has
+a chance to do its "remove everything" startup protocol. The usual
+result of this is that libvirt will successfully add its private
+chains (e.g. LIBVIRT_INP, etc), but then fail when it tries to add a
+rule jumping to one of those chains (because in the interim, firewalld
+has deleted the new chains).
+
+The solution is for libvirt to preface it's direct calling to iptables
+with a iptables command sent via firewalld's passthrough command
+API. Since commands sent to firewalld are completed synchronously, and
+since firewalld won't service them until it has completed its own
+initialization, this will assure that by the time libvirt starts
+calling iptables to add rules, that firewalld will not be following up
+by deleting any of those rules.
+
+To minimize the amount of extra overhead, we request the simplest
+iptables command possible: "iptables -V" (and aside from logging a
+debug message, we ignore the result, for good measure).
+
+(This patch is being done *before* the patch that switches to calling
+iptables directly, so that everything will function properly with any
+fractional part of the series applied).
+
+https://bugzilla.redhat.com/1607929
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 070690538a1ed301b004c542d94b13ee9bffc9d6)
+
+Conflicts: src/util/viriptables.c:
+    one line of code in context moved during g_autoptr conversion.
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20210116035151.1066734-8-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/libvirt_private.syms |  1 +
+ src/util/virfirewall.c   | 30 ++++++++++++++++++++++++++++++
+ src/util/virfirewall.h   |  2 ++
+ src/util/viriptables.c   |  7 +++++++
+ 4 files changed, 40 insertions(+)
+
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index edc53ce899..9d87e2a27b 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -2080,6 +2080,7 @@ virFileCacheSetPriv;
+ # util/virfirewall.h
+ virFirewallAddRuleFull;
+ virFirewallApply;
++virFirewallBackendSynchronize;
+ virFirewallFree;
+ virFirewallNew;
+ virFirewallRemoveRule;
+diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c
+index 520d515c11..66d20d3f17 100644
+--- a/src/util/virfirewall.c
++++ b/src/util/virfirewall.c
+@@ -653,6 +653,36 @@ virFirewallApplyRuleFirewallD(virFirewallRulePtr rule,
+     return virFirewallDApplyRule(rule->layer, rule->args, rule->argsLen, ignoreErrors, output);
+ }
+ 
++
++void
++virFirewallBackendSynchronize(void)
++{
++    const char *arg = "-V";
++    g_autofree char *output = NULL;
++
++    switch (currentBackend) {
++    case VIR_FIREWALL_BACKEND_DIRECT:
++        /* nobody to synchronize with */
++        break;
++    case VIR_FIREWALL_BACKEND_FIREWALLD:
++        /* Send a simple rule via firewalld's passthrough iptables
++         * command so that we'll be sure firewalld has fully
++         * initialized and caught up with its internal queue of
++         * iptables commands. Waiting for this will prevent our own
++         * directly-executed iptables commands from being run while
++         * firewalld is still initializing.
++         */
++        ignore_value(virFirewallDApplyRule(VIR_FIREWALL_LAYER_IPV4,
++                                           (char **)&arg, 1, true, &output));
++        VIR_DEBUG("Result of 'iptables -V' via firewalld: %s", NULLSTR(output));
++        break;
++    case VIR_FIREWALL_BACKEND_AUTOMATIC:
++    case VIR_FIREWALL_BACKEND_LAST:
++        break;
++    }
++}
++
++
+ static int
+ virFirewallApplyRule(virFirewallPtr firewall,
+                      virFirewallRulePtr rule,
+diff --git a/src/util/virfirewall.h b/src/util/virfirewall.h
+index fda3cdec01..3db0864380 100644
+--- a/src/util/virfirewall.h
++++ b/src/util/virfirewall.h
+@@ -111,4 +111,6 @@ void virFirewallStartRollback(virFirewallPtr firewall,
+ 
+ int virFirewallApply(virFirewallPtr firewall);
+ 
++void virFirewallBackendSynchronize(void);
++
+ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virFirewall, virFirewallFree);
+diff --git a/src/util/viriptables.c b/src/util/viriptables.c
+index 6b3a025880..41544b7f36 100644
+--- a/src/util/viriptables.c
++++ b/src/util/viriptables.c
+@@ -154,6 +154,13 @@ iptablesSetupPrivateChains(virFirewallLayer layer)
+ 
+     fw = virFirewallNew();
+ 
++    /* When the backend is firewalld, we need to make sure that
++     * firewalld has been fully started and completed its
++     * initialization, otherwise firewalld might delete our rules soon
++     * after we add them!
++     */
++    virFirewallBackendSynchronize();
++
+     virFirewallStartTransaction(fw, 0);
+ 
+     for (i = 0; i < G_N_ELEMENTS(data); i++)
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-by-default.patch b/SOURCES/libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-by-default.patch
new file mode 100644
index 0000000..6446cf4
--- /dev/null
+++ b/SOURCES/libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-by-default.patch
@@ -0,0 +1,225 @@
+From d7703d11a44505d1a17001d8cfd36bf74d20b710 Mon Sep 17 00:00:00 2001
+Message-Id: <d7703d11a44505d1a17001d8cfd36bf74d20b710@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Fri, 15 Jan 2021 22:51:46 -0500
+Subject: [PATCH] util/tests: enable locking on iptables/ebtables commandlines
+ by default
+
+iptables and ip6tables have had a "-w" commandline option to grab a
+systemwide lock that prevents two iptables invocations from modifying
+the iptables chains since 2013 (upstream commit 93587a04 in
+iptables-1.4.20).  Similarly, ebtables has had a "--concurrent"
+commandline option for the same purpose since 2011 (in the upstream
+ebtables commit f9b4bcb93, which was present in ebtables-2.0.10.4).
+
+Libvirt added code to conditionally use the commandline option for
+iptables/ip6tables in upstream commit ba95426d6f (libvirt-1.2.0,
+November 2013), and for ebtables in upstream commit dc33e6e4a5
+(libvirt-1.2.11, November 2014) (the latter actually *re*-added the
+locking for iptables/ip6tables, as it had accidentally been removed
+during a refactor of firewall code in the interim).
+
+I say "conditionally" because a check was made during firewall module
+initialization that tried executing a test command with the
+-w/--concurrent option, and only continued using it for actual
+commands if that test command completed successfully. At the time the
+code was added this was a reasonable thing to do, as it had been less
+than a year since introduction of -w to iptables, so many distros
+supported by libvirt were still using iptables (and possibly even
+ebtables) versions too old to have the new commandline options.
+
+It is now 2020, and as far as I can discern from repology.org (and
+manually examining a RHEL7.9 system), every version of every distro
+that is supported by libvirt now uses new enough versions of both
+iptables and ebtables that they all have support for -w/--concurrent.
+That means we can finally remove the conditional code and simply
+always use them.
+
+https://bugzilla.redhat.com/1607929
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 0a867cd895f06134d24eb27070285bb4b50c088f)
+Message-Id: <20210116035151.1066734-4-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/libvirt_private.syms         |  1 -
+ src/util/virfirewall.c           | 64 ++------------------------------
+ src/util/virfirewall.h           |  2 -
+ tests/networkxml2firewalltest.c  |  2 -
+ tests/nwfilterebiptablestest.c   |  2 -
+ tests/nwfilterxml2firewalltest.c |  2 -
+ tests/virfirewalltest.c          |  2 -
+ 7 files changed, 3 insertions(+), 72 deletions(-)
+
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index d6598c2514..edc53ce899 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -2089,7 +2089,6 @@ virFirewallRuleAddArgList;
+ virFirewallRuleAddArgSet;
+ virFirewallRuleGetArgCount;
+ virFirewallSetBackend;
+-virFirewallSetLockOverride;
+ virFirewallStartRollback;
+ virFirewallStartTransaction;
+ 
+diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c
+index c2de2bccae..2e3b02402e 100644
+--- a/src/util/virfirewall.c
++++ b/src/util/virfirewall.c
+@@ -97,59 +97,6 @@ virFirewallOnceInit(void)
+ 
+ VIR_ONCE_GLOBAL_INIT(virFirewall);
+ 
+-static bool iptablesUseLock;
+-static bool ip6tablesUseLock;
+-static bool ebtablesUseLock;
+-static bool lockOverride; /* true to avoid lock probes */
+-
+-void
+-virFirewallSetLockOverride(bool avoid)
+-{
+-    lockOverride = avoid;
+-    if (avoid) {
+-        /* add the lock option to all commands */
+-        iptablesUseLock = true;
+-        ip6tablesUseLock = true;
+-        ebtablesUseLock = true;
+-    }
+-}
+-
+-static void
+-virFirewallCheckUpdateLock(bool *lockflag,
+-                           const char *const*args)
+-{
+-    int status; /* Ignore failed commands without logging them */
+-    g_autoptr(virCommand) cmd = virCommandNewArgs(args);
+-    if (virCommandRun(cmd, &status) < 0 || status) {
+-        VIR_INFO("locking not supported by %s", args[0]);
+-    } else {
+-        VIR_INFO("using locking for %s", args[0]);
+-        *lockflag = true;
+-    }
+-}
+-
+-static void
+-virFirewallCheckUpdateLocking(void)
+-{
+-    const char *iptablesArgs[] = {
+-        IPTABLES_PATH, "-w", "-L", "-n", NULL,
+-    };
+-    const char *ip6tablesArgs[] = {
+-        IP6TABLES_PATH, "-w", "-L", "-n", NULL,
+-    };
+-    const char *ebtablesArgs[] = {
+-        EBTABLES_PATH, "--concurrent", "-L", NULL,
+-    };
+-    if (lockOverride)
+-        return;
+-    virFirewallCheckUpdateLock(&iptablesUseLock,
+-                               iptablesArgs);
+-    virFirewallCheckUpdateLock(&ip6tablesUseLock,
+-                               ip6tablesArgs);
+-    virFirewallCheckUpdateLock(&ebtablesUseLock,
+-                               ebtablesArgs);
+-}
+-
+ static int
+ virFirewallValidateBackend(virFirewallBackend backend)
+ {
+@@ -197,8 +144,6 @@ virFirewallValidateBackend(virFirewallBackend backend)
+ 
+     currentBackend = backend;
+ 
+-    virFirewallCheckUpdateLocking();
+-
+     return 0;
+ }
+ 
+@@ -363,16 +308,13 @@ virFirewallAddRuleFullV(virFirewallPtr firewall,
+ 
+     switch (rule->layer) {
+     case VIR_FIREWALL_LAYER_ETHERNET:
+-        if (ebtablesUseLock)
+-            ADD_ARG(rule, "--concurrent");
++        ADD_ARG(rule, "--concurrent");
+         break;
+     case VIR_FIREWALL_LAYER_IPV4:
+-        if (iptablesUseLock)
+-            ADD_ARG(rule, "-w");
++        ADD_ARG(rule, "-w");
+         break;
+     case VIR_FIREWALL_LAYER_IPV6:
+-        if (ip6tablesUseLock)
+-            ADD_ARG(rule, "-w");
++        ADD_ARG(rule, "-w");
+         break;
+     case VIR_FIREWALL_LAYER_LAST:
+         break;
+diff --git a/src/util/virfirewall.h b/src/util/virfirewall.h
+index 6148f46827..fda3cdec01 100644
+--- a/src/util/virfirewall.h
++++ b/src/util/virfirewall.h
+@@ -111,6 +111,4 @@ void virFirewallStartRollback(virFirewallPtr firewall,
+ 
+ int virFirewallApply(virFirewallPtr firewall);
+ 
+-void virFirewallSetLockOverride(bool avoid);
+-
+ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virFirewall, virFirewallFree);
+diff --git a/tests/networkxml2firewalltest.c b/tests/networkxml2firewalltest.c
+index 0ad5e2303b..886b268319 100644
+--- a/tests/networkxml2firewalltest.c
++++ b/tests/networkxml2firewalltest.c
+@@ -152,8 +152,6 @@ mymain(void)
+             ret = -1; \
+     } while (0)
+ 
+-    virFirewallSetLockOverride(true);
+-
+     if (virFirewallSetBackend(VIR_FIREWALL_BACKEND_DIRECT) < 0) {
+         if (!hasNetfilterTools()) {
+             fprintf(stderr, "iptables/ip6tables/ebtables tools not present");
+diff --git a/tests/nwfilterebiptablestest.c b/tests/nwfilterebiptablestest.c
+index e70f0e2400..adce7430a9 100644
+--- a/tests/nwfilterebiptablestest.c
++++ b/tests/nwfilterebiptablestest.c
+@@ -510,8 +510,6 @@ mymain(void)
+ {
+     int ret = 0;
+ 
+-    virFirewallSetLockOverride(true);
+-
+     if (virFirewallSetBackend(VIR_FIREWALL_BACKEND_DIRECT) < 0) {
+         if (!hasNetfilterTools()) {
+             fprintf(stderr, "iptables/ip6tables/ebtables tools not present");
+diff --git a/tests/nwfilterxml2firewalltest.c b/tests/nwfilterxml2firewalltest.c
+index c97f83b24a..73f7991a96 100644
+--- a/tests/nwfilterxml2firewalltest.c
++++ b/tests/nwfilterxml2firewalltest.c
+@@ -459,8 +459,6 @@ mymain(void)
+             ret = -1; \
+     } while (0)
+ 
+-    virFirewallSetLockOverride(true);
+-
+     if (virFirewallSetBackend(VIR_FIREWALL_BACKEND_DIRECT) < 0) {
+         if (!hasNetfilterTools()) {
+             fprintf(stderr, "iptables/ip6tables/ebtables tools not present");
+diff --git a/tests/virfirewalltest.c b/tests/virfirewalltest.c
+index 195163a985..1ec768d302 100644
+--- a/tests/virfirewalltest.c
++++ b/tests/virfirewalltest.c
+@@ -1141,8 +1141,6 @@ mymain(void)
+     RUN_TEST_DIRECT(name, method)
+ # endif /* ! WITH_DBUS */
+ 
+-    virFirewallSetLockOverride(true);
+-
+     RUN_TEST("single group", testFirewallSingleGroup);
+     RUN_TEST("remove rule", testFirewallRemoveRule);
+     RUN_TEST("many groups", testFirewallManyGroups);
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-in-unit-tests.patch b/SOURCES/libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-in-unit-tests.patch
new file mode 100644
index 0000000..6230734
--- /dev/null
+++ b/SOURCES/libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-in-unit-tests.patch
@@ -0,0 +1,6497 @@
+From 4dcb98488fe7049c914a9e2bd82d2fcae834bba5 Mon Sep 17 00:00:00 2001
+Message-Id: <4dcb98488fe7049c914a9e2bd82d2fcae834bba5@dist-git>
+From: Laine Stump <laine@redhat.com>
+Date: Fri, 15 Jan 2021 22:51:45 -0500
+Subject: [PATCH] util/tests: enable locking on iptables/ebtables commandlines
+ in unit tests
+
+All the unit tests that use iptables/ip6tables/ebtables have been
+written to omit the locking/exclusive use primitive on the generated
+commandlines. Even though none of the tests actually execute those
+commands (and so it doesn't matter for purposes of the test whether or
+not the commands support these options), it still made sense when some
+systems had these locking options and some didn't.
+
+We are now at a point where every supported Linux distro has supported
+the locking options on these commands for quite a long time, and are
+going to make their use non-optional. As a first step, this patch uses
+the virFirewallSetLockOverride() function, which is called at the
+beginning of all firewall-related tests, to set all the bools
+controlling whether or not the locking options are used to true. This
+means that all the test cases must be updated to include the proper
+locking option in their commandlines.
+
+The change to make actual execs of the commands unconditionally use
+the locking option will be in an upcoming patch - this one affects
+only the unit tests.
+
+https://bugzilla.redhat.com/1607929
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit e66451f685e29ffe4be5a060ef64b19961ad4bb5)
+
+Conflicts:
+  tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.args:
+     exists only upstream
+
+  tests/virfirewalltest.c:
+     minor merge conflict due to glib conversion upstream.
+
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20210116035151.1066734-3-laine@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virfirewall.c                        |   6 +
+ tests/networkxml2firewalldata/base.args       |  34 ++
+ .../nat-default-linux.args                    |  19 +
+ .../nat-ipv6-linux.args                       |  30 ++
+ .../nat-many-ips-linux.args                   |  33 ++
+ .../nat-no-dhcp-linux.args                    |  29 ++
+ .../nat-tftp-linux.args                       |  21 +
+ .../route-default-linux.args                  |  14 +
+ tests/nwfilterebiptablestest.c                | 464 +++++++++---------
+ .../ah-ipv6-linux.args                        |   9 +
+ tests/nwfilterxml2firewalldata/ah-linux.args  |   9 +
+ .../all-ipv6-linux.args                       |   9 +
+ tests/nwfilterxml2firewalldata/all-linux.args |   9 +
+ tests/nwfilterxml2firewalldata/arp-linux.args |   5 +
+ .../comment-linux.args                        |  19 +
+ .../conntrack-linux.args                      |   7 +
+ .../esp-ipv6-linux.args                       |   9 +
+ tests/nwfilterxml2firewalldata/esp-linux.args |   9 +
+ .../example-1-linux.args                      |  12 +
+ .../example-2-linux.args                      |  10 +
+ .../hex-data-linux.args                       |  10 +
+ .../icmp-direction-linux.args                 |   6 +
+ .../icmp-direction2-linux.args                |   6 +
+ .../icmp-direction3-linux.args                |   6 +
+ .../nwfilterxml2firewalldata/icmp-linux.args  |   3 +
+ .../icmpv6-linux.args                         |   4 +
+ .../nwfilterxml2firewalldata/igmp-linux.args  |   9 +
+ tests/nwfilterxml2firewalldata/ip-linux.args  |   3 +
+ .../nwfilterxml2firewalldata/ipset-linux.args |  18 +
+ .../ipt-no-macspoof-linux.args                |   2 +
+ .../nwfilterxml2firewalldata/ipv6-linux.args  |  15 +
+ .../nwfilterxml2firewalldata/iter1-linux.args |   9 +
+ .../nwfilterxml2firewalldata/iter2-linux.args | 171 +++++++
+ .../nwfilterxml2firewalldata/iter3-linux.args |  15 +
+ tests/nwfilterxml2firewalldata/mac-linux.args |   4 +
+ .../nwfilterxml2firewalldata/rarp-linux.args  |   6 +
+ .../sctp-ipv6-linux.args                      |   9 +
+ .../nwfilterxml2firewalldata/sctp-linux.args  |   9 +
+ tests/nwfilterxml2firewalldata/stp-linux.args |  11 +
+ .../target-linux.args                         |  33 ++
+ .../target2-linux.args                        |  12 +
+ .../tcp-ipv6-linux.args                       |   9 +
+ tests/nwfilterxml2firewalldata/tcp-linux.args |  13 +
+ .../udp-ipv6-linux.args                       |   9 +
+ tests/nwfilterxml2firewalldata/udp-linux.args |   9 +
+ .../udplite-ipv6-linux.args                   |   9 +
+ .../udplite-linux.args                        |   9 +
+ .../nwfilterxml2firewalldata/vlan-linux.args  |   7 +
+ tests/nwfilterxml2firewalltest.c              | 144 +++---
+ tests/virfirewalltest.c                       | 112 +++--
+ 50 files changed, 1081 insertions(+), 358 deletions(-)
+
+diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c
+index ee72b579e4..c2de2bccae 100644
+--- a/src/util/virfirewall.c
++++ b/src/util/virfirewall.c
+@@ -106,6 +106,12 @@ void
+ virFirewallSetLockOverride(bool avoid)
+ {
+     lockOverride = avoid;
++    if (avoid) {
++        /* add the lock option to all commands */
++        iptablesUseLock = true;
++        ip6tablesUseLock = true;
++        ebtablesUseLock = true;
++    }
+ }
+ 
+ static void
+diff --git a/tests/networkxml2firewalldata/base.args b/tests/networkxml2firewalldata/base.args
+index 0e71bf3a64..056ee12758 100644
+--- a/tests/networkxml2firewalldata/base.args
++++ b/tests/networkxml2firewalldata/base.args
+@@ -1,116 +1,150 @@
+ iptables \
++-w \
+ --table filter \
+ --list-rules
+ iptables \
++-w \
+ --table nat \
+ --list-rules
+ iptables \
++-w \
+ --table mangle \
+ --list-rules
+ iptables \
++-w \
+ --table filter \
+ --new-chain LIBVIRT_INP
+ iptables \
++-w \
+ --table filter \
+ --insert INPUT \
+ --jump LIBVIRT_INP
+ iptables \
++-w \
+ --table filter \
+ --new-chain LIBVIRT_OUT
+ iptables \
++-w \
+ --table filter \
+ --insert OUTPUT \
+ --jump LIBVIRT_OUT
+ iptables \
++-w \
+ --table filter \
+ --new-chain LIBVIRT_FWO
+ iptables \
++-w \
+ --table filter \
+ --insert FORWARD \
+ --jump LIBVIRT_FWO
+ iptables \
++-w \
+ --table filter \
+ --new-chain LIBVIRT_FWI
+ iptables \
++-w \
+ --table filter \
+ --insert FORWARD \
+ --jump LIBVIRT_FWI
+ iptables \
++-w \
+ --table filter \
+ --new-chain LIBVIRT_FWX
+ iptables \
++-w \
+ --table filter \
+ --insert FORWARD \
+ --jump LIBVIRT_FWX
+ iptables \
++-w \
+ --table nat \
+ --new-chain LIBVIRT_PRT
+ iptables \
++-w \
+ --table nat \
+ --insert POSTROUTING \
+ --jump LIBVIRT_PRT
+ iptables \
++-w \
+ --table mangle \
+ --new-chain LIBVIRT_PRT
+ iptables \
++-w \
+ --table mangle \
+ --insert POSTROUTING \
+ --jump LIBVIRT_PRT
+ ip6tables \
++-w \
+ --table filter \
+ --list-rules
+ ip6tables \
++-w \
+ --table nat \
+ --list-rules
+ ip6tables \
++-w \
+ --table mangle \
+ --list-rules
+ ip6tables \
++-w \
+ --table filter \
+ --new-chain LIBVIRT_INP
+ ip6tables \
++-w \
+ --table filter \
+ --insert INPUT \
+ --jump LIBVIRT_INP
+ ip6tables \
++-w \
+ --table filter \
+ --new-chain LIBVIRT_OUT
+ ip6tables \
++-w \
+ --table filter \
+ --insert OUTPUT \
+ --jump LIBVIRT_OUT
+ ip6tables \
++-w \
+ --table filter \
+ --new-chain LIBVIRT_FWO
+ ip6tables \
++-w \
+ --table filter \
+ --insert FORWARD \
+ --jump LIBVIRT_FWO
+ ip6tables \
++-w \
+ --table filter \
+ --new-chain LIBVIRT_FWI
+ ip6tables \
++-w \
+ --table filter \
+ --insert FORWARD \
+ --jump LIBVIRT_FWI
+ ip6tables \
++-w \
+ --table filter \
+ --new-chain LIBVIRT_FWX
+ ip6tables \
++-w \
+ --table filter \
+ --insert FORWARD \
+ --jump LIBVIRT_FWX
+ ip6tables \
++-w \
+ --table nat \
+ --new-chain LIBVIRT_PRT
+ ip6tables \
++-w \
+ --table nat \
+ --insert POSTROUTING \
+ --jump LIBVIRT_PRT
+ ip6tables \
++-w \
+ --table mangle \
+ --new-chain LIBVIRT_PRT
+ ip6tables \
++-w \
+ --table mangle \
+ --insert POSTROUTING \
+ --jump LIBVIRT_PRT
+diff --git a/tests/networkxml2firewalldata/nat-default-linux.args b/tests/networkxml2firewalldata/nat-default-linux.args
+index ab18f30bd0..3cfa61333c 100644
+--- a/tests/networkxml2firewalldata/nat-default-linux.args
++++ b/tests/networkxml2firewalldata/nat-default-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -6,6 +7,7 @@ iptables \
+ --destination-port 67 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -13,6 +15,7 @@ iptables \
+ --destination-port 67 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -20,6 +23,7 @@ iptables \
+ --destination-port 68 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -27,6 +31,7 @@ iptables \
+ --destination-port 68 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -34,6 +39,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -41,6 +47,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -48,6 +55,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -55,28 +63,33 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --in-interface virbr0 \
+ --jump REJECT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --out-interface virbr0 \
+ --jump REJECT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWX \
+ --in-interface virbr0 \
+ --out-interface virbr0 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --source 192.168.122.0/24 \
+ --in-interface virbr0 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --destination 192.168.122.0/24 \
+@@ -85,12 +98,14 @@ iptables \
+ --ctstate ESTABLISHED,RELATED \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 '!' \
+ --destination 192.168.122.0/24 \
+ --jump MASQUERADE
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+@@ -99,6 +114,7 @@ iptables \
+ --jump MASQUERADE \
+ --to-ports 1024-65535
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+@@ -107,18 +123,21 @@ iptables \
+ --jump MASQUERADE \
+ --to-ports 1024-65535
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+ --destination 255.255.255.255/32 \
+ --jump RETURN
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+ --destination 224.0.0.0/24 \
+ --jump RETURN
+ iptables \
++-w \
+ --table mangle \
+ --insert LIBVIRT_PRT \
+ --out-interface virbr0 \
+diff --git a/tests/networkxml2firewalldata/nat-ipv6-linux.args b/tests/networkxml2firewalldata/nat-ipv6-linux.args
+index 05d9ee33ca..ce295cbc6d 100644
+--- a/tests/networkxml2firewalldata/nat-ipv6-linux.args
++++ b/tests/networkxml2firewalldata/nat-ipv6-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -6,6 +7,7 @@ iptables \
+ --destination-port 67 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -13,6 +15,7 @@ iptables \
+ --destination-port 67 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -20,6 +23,7 @@ iptables \
+ --destination-port 68 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -27,6 +31,7 @@ iptables \
+ --destination-port 68 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -34,6 +39,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -41,6 +47,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -48,6 +55,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -55,38 +63,45 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --in-interface virbr0 \
+ --jump REJECT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --out-interface virbr0 \
+ --jump REJECT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWX \
+ --in-interface virbr0 \
+ --out-interface virbr0 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --in-interface virbr0 \
+ --jump REJECT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --out-interface virbr0 \
+ --jump REJECT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWX \
+ --in-interface virbr0 \
+ --out-interface virbr0 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -94,6 +109,7 @@ ip6tables \
+ --destination-port 53 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -101,6 +117,7 @@ ip6tables \
+ --destination-port 53 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -108,6 +125,7 @@ ip6tables \
+ --destination-port 53 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -115,6 +133,7 @@ ip6tables \
+ --destination-port 53 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -122,6 +141,7 @@ ip6tables \
+ --destination-port 547 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -129,12 +149,14 @@ ip6tables \
+ --destination-port 546 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --source 192.168.122.0/24 \
+ --in-interface virbr0 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --destination 192.168.122.0/24 \
+@@ -143,12 +165,14 @@ iptables \
+ --ctstate ESTABLISHED,RELATED \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 '!' \
+ --destination 192.168.122.0/24 \
+ --jump MASQUERADE
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+@@ -157,6 +181,7 @@ iptables \
+ --jump MASQUERADE \
+ --to-ports 1024-65535
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+@@ -165,30 +190,35 @@ iptables \
+ --jump MASQUERADE \
+ --to-ports 1024-65535
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+ --destination 255.255.255.255/32 \
+ --jump RETURN
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+ --destination 224.0.0.0/24 \
+ --jump RETURN
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --source 2001:db8:ca2:2::/64 \
+ --in-interface virbr0 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --destination 2001:db8:ca2:2::/64 \
+ --out-interface virbr0 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table mangle \
+ --insert LIBVIRT_PRT \
+ --out-interface virbr0 \
+diff --git a/tests/networkxml2firewalldata/nat-many-ips-linux.args b/tests/networkxml2firewalldata/nat-many-ips-linux.args
+index 82e1380f51..ba7f234b82 100644
+--- a/tests/networkxml2firewalldata/nat-many-ips-linux.args
++++ b/tests/networkxml2firewalldata/nat-many-ips-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -6,6 +7,7 @@ iptables \
+ --destination-port 67 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -13,6 +15,7 @@ iptables \
+ --destination-port 67 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -20,6 +23,7 @@ iptables \
+ --destination-port 68 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -27,6 +31,7 @@ iptables \
+ --destination-port 68 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -34,6 +39,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -41,6 +47,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -48,6 +55,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -55,28 +63,33 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --in-interface virbr0 \
+ --jump REJECT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --out-interface virbr0 \
+ --jump REJECT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWX \
+ --in-interface virbr0 \
+ --out-interface virbr0 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --source 192.168.122.0/24 \
+ --in-interface virbr0 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --destination 192.168.122.0/24 \
+@@ -85,12 +98,14 @@ iptables \
+ --ctstate ESTABLISHED,RELATED \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 '!' \
+ --destination 192.168.122.0/24 \
+ --jump MASQUERADE
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+@@ -99,6 +114,7 @@ iptables \
+ --jump MASQUERADE \
+ --to-ports 1024-65535
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+@@ -107,24 +123,28 @@ iptables \
+ --jump MASQUERADE \
+ --to-ports 1024-65535
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+ --destination 255.255.255.255/32 \
+ --jump RETURN
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+ --destination 224.0.0.0/24 \
+ --jump RETURN
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --source 192.168.128.0/24 \
+ --in-interface virbr0 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --destination 192.168.128.0/24 \
+@@ -133,12 +153,14 @@ iptables \
+ --ctstate ESTABLISHED,RELATED \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.128.0/24 '!' \
+ --destination 192.168.128.0/24 \
+ --jump MASQUERADE
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.128.0/24 \
+@@ -147,6 +169,7 @@ iptables \
+ --jump MASQUERADE \
+ --to-ports 1024-65535
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.128.0/24 \
+@@ -155,24 +178,28 @@ iptables \
+ --jump MASQUERADE \
+ --to-ports 1024-65535
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.128.0/24 \
+ --destination 255.255.255.255/32 \
+ --jump RETURN
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.128.0/24 \
+ --destination 224.0.0.0/24 \
+ --jump RETURN
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --source 192.168.150.0/24 \
+ --in-interface virbr0 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --destination 192.168.150.0/24 \
+@@ -181,12 +208,14 @@ iptables \
+ --ctstate ESTABLISHED,RELATED \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.150.0/24 '!' \
+ --destination 192.168.150.0/24 \
+ --jump MASQUERADE
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.150.0/24 \
+@@ -195,6 +224,7 @@ iptables \
+ --jump MASQUERADE \
+ --to-ports 1024-65535
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.150.0/24 \
+@@ -203,18 +233,21 @@ iptables \
+ --jump MASQUERADE \
+ --to-ports 1024-65535
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.150.0/24 \
+ --destination 255.255.255.255/32 \
+ --jump RETURN
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.150.0/24 \
+ --destination 224.0.0.0/24 \
+ --jump RETURN
+ iptables \
++-w \
+ --table mangle \
+ --insert LIBVIRT_PRT \
+ --out-interface virbr0 \
+diff --git a/tests/networkxml2firewalldata/nat-no-dhcp-linux.args b/tests/networkxml2firewalldata/nat-no-dhcp-linux.args
+index 8954cc5473..1e5aa05231 100644
+--- a/tests/networkxml2firewalldata/nat-no-dhcp-linux.args
++++ b/tests/networkxml2firewalldata/nat-no-dhcp-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -6,6 +7,7 @@ iptables \
+ --destination-port 67 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -13,6 +15,7 @@ iptables \
+ --destination-port 67 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -20,6 +23,7 @@ iptables \
+ --destination-port 68 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -27,6 +31,7 @@ iptables \
+ --destination-port 68 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -34,6 +39,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -41,6 +47,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -48,6 +55,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -55,38 +63,45 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --in-interface virbr0 \
+ --jump REJECT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --out-interface virbr0 \
+ --jump REJECT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWX \
+ --in-interface virbr0 \
+ --out-interface virbr0 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --in-interface virbr0 \
+ --jump REJECT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --out-interface virbr0 \
+ --jump REJECT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWX \
+ --in-interface virbr0 \
+ --out-interface virbr0 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -94,6 +109,7 @@ ip6tables \
+ --destination-port 53 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -101,6 +117,7 @@ ip6tables \
+ --destination-port 53 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -108,6 +125,7 @@ ip6tables \
+ --destination-port 53 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -115,6 +133,7 @@ ip6tables \
+ --destination-port 53 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -122,6 +141,7 @@ ip6tables \
+ --destination-port 547 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -129,12 +149,14 @@ ip6tables \
+ --destination-port 546 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --source 192.168.122.0/24 \
+ --in-interface virbr0 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --destination 192.168.122.0/24 \
+@@ -143,12 +165,14 @@ iptables \
+ --ctstate ESTABLISHED,RELATED \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 '!' \
+ --destination 192.168.122.0/24 \
+ --jump MASQUERADE
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+@@ -157,6 +181,7 @@ iptables \
+ --jump MASQUERADE \
+ --to-ports 1024-65535
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+@@ -165,24 +190,28 @@ iptables \
+ --jump MASQUERADE \
+ --to-ports 1024-65535
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+ --destination 255.255.255.255/32 \
+ --jump RETURN
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+ --destination 224.0.0.0/24 \
+ --jump RETURN
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --source 2001:db8:ca2:2::/64 \
+ --in-interface virbr0 \
+ --jump ACCEPT
+ ip6tables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --destination 2001:db8:ca2:2::/64 \
+diff --git a/tests/networkxml2firewalldata/nat-tftp-linux.args b/tests/networkxml2firewalldata/nat-tftp-linux.args
+index 88e9929b62..565fff737c 100644
+--- a/tests/networkxml2firewalldata/nat-tftp-linux.args
++++ b/tests/networkxml2firewalldata/nat-tftp-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -6,6 +7,7 @@ iptables \
+ --destination-port 67 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -13,6 +15,7 @@ iptables \
+ --destination-port 67 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -20,6 +23,7 @@ iptables \
+ --destination-port 68 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -27,6 +31,7 @@ iptables \
+ --destination-port 68 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -34,6 +39,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -41,6 +47,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -48,6 +55,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -55,6 +63,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -62,6 +71,7 @@ iptables \
+ --destination-port 69 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -69,28 +79,33 @@ iptables \
+ --destination-port 69 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --in-interface virbr0 \
+ --jump REJECT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --out-interface virbr0 \
+ --jump REJECT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWX \
+ --in-interface virbr0 \
+ --out-interface virbr0 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --source 192.168.122.0/24 \
+ --in-interface virbr0 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --destination 192.168.122.0/24 \
+@@ -99,12 +114,14 @@ iptables \
+ --ctstate ESTABLISHED,RELATED \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 '!' \
+ --destination 192.168.122.0/24 \
+ --jump MASQUERADE
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+@@ -113,6 +130,7 @@ iptables \
+ --jump MASQUERADE \
+ --to-ports 1024-65535
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+@@ -121,18 +139,21 @@ iptables \
+ --jump MASQUERADE \
+ --to-ports 1024-65535
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+ --destination 255.255.255.255/32 \
+ --jump RETURN
+ iptables \
++-w \
+ --table nat \
+ --insert LIBVIRT_PRT \
+ --source 192.168.122.0/24 \
+ --destination 224.0.0.0/24 \
+ --jump RETURN
+ iptables \
++-w \
+ --table mangle \
+ --insert LIBVIRT_PRT \
+ --out-interface virbr0 \
+diff --git a/tests/networkxml2firewalldata/route-default-linux.args b/tests/networkxml2firewalldata/route-default-linux.args
+index c427d9602d..a7b969c077 100644
+--- a/tests/networkxml2firewalldata/route-default-linux.args
++++ b/tests/networkxml2firewalldata/route-default-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -6,6 +7,7 @@ iptables \
+ --destination-port 67 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -13,6 +15,7 @@ iptables \
+ --destination-port 67 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -20,6 +23,7 @@ iptables \
+ --destination-port 68 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -27,6 +31,7 @@ iptables \
+ --destination-port 68 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -34,6 +39,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_INP \
+ --in-interface virbr0 \
+@@ -41,6 +47,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -48,6 +55,7 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_OUT \
+ --out-interface virbr0 \
+@@ -55,34 +63,40 @@ iptables \
+ --destination-port 53 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --in-interface virbr0 \
+ --jump REJECT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --out-interface virbr0 \
+ --jump REJECT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWX \
+ --in-interface virbr0 \
+ --out-interface virbr0 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWO \
+ --source 192.168.122.0/24 \
+ --in-interface virbr0 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table filter \
+ --insert LIBVIRT_FWI \
+ --destination 192.168.122.0/24 \
+ --out-interface virbr0 \
+ --jump ACCEPT
+ iptables \
++-w \
+ --table mangle \
+ --insert LIBVIRT_PRT \
+ --out-interface virbr0 \
+diff --git a/tests/nwfilterebiptablestest.c b/tests/nwfilterebiptablestest.c
+index 3e6c335d4e..e70f0e2400 100644
+--- a/tests/nwfilterebiptablestest.c
++++ b/tests/nwfilterebiptablestest.c
+@@ -36,34 +36,34 @@
+ 
+ 
+ #define VIR_NWFILTER_NEW_RULES_TEARDOWN \
+-    "iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" \
+-    "iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n" \
+-    "iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" \
+-    "iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" \
+-    "iptables -F FP-vnet0\n" \
+-    "iptables -X FP-vnet0\n" \
+-    "iptables -F FJ-vnet0\n" \
+-    "iptables -X FJ-vnet0\n" \
+-    "iptables -F HJ-vnet0\n" \
+-    "iptables -X HJ-vnet0\n" \
+-    "ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" \
+-    "ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n" \
+-    "ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" \
+-    "ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" \
+-    "ip6tables -F FP-vnet0\n" \
+-    "ip6tables -X FP-vnet0\n" \
+-    "ip6tables -F FJ-vnet0\n" \
+-    "ip6tables -X FJ-vnet0\n" \
+-    "ip6tables -F HJ-vnet0\n" \
+-    "ip6tables -X HJ-vnet0\n" \
+-    "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-J-vnet0\n" \
+-    "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-P-vnet0\n" \
+-    "ebtables -t nat -L libvirt-J-vnet0\n" \
+-    "ebtables -t nat -L libvirt-P-vnet0\n" \
+-    "ebtables -t nat -F libvirt-J-vnet0\n" \
+-    "ebtables -t nat -X libvirt-J-vnet0\n" \
+-    "ebtables -t nat -F libvirt-P-vnet0\n" \
+-    "ebtables -t nat -X libvirt-P-vnet0\n"
++    "iptables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" \
++    "iptables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n" \
++    "iptables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" \
++    "iptables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" \
++    "iptables -w -F FP-vnet0\n" \
++    "iptables -w -X FP-vnet0\n" \
++    "iptables -w -F FJ-vnet0\n" \
++    "iptables -w -X FJ-vnet0\n" \
++    "iptables -w -F HJ-vnet0\n" \
++    "iptables -w -X HJ-vnet0\n" \
++    "ip6tables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" \
++    "ip6tables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n" \
++    "ip6tables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" \
++    "ip6tables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" \
++    "ip6tables -w -F FP-vnet0\n" \
++    "ip6tables -w -X FP-vnet0\n" \
++    "ip6tables -w -F FJ-vnet0\n" \
++    "ip6tables -w -X FJ-vnet0\n" \
++    "ip6tables -w -F HJ-vnet0\n" \
++    "ip6tables -w -X HJ-vnet0\n" \
++    "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-J-vnet0\n" \
++    "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-P-vnet0\n" \
++    "ebtables --concurrent -t nat -L libvirt-J-vnet0\n" \
++    "ebtables --concurrent -t nat -L libvirt-P-vnet0\n" \
++    "ebtables --concurrent -t nat -F libvirt-J-vnet0\n" \
++    "ebtables --concurrent -t nat -X libvirt-J-vnet0\n" \
++    "ebtables --concurrent -t nat -F libvirt-P-vnet0\n" \
++    "ebtables --concurrent -t nat -X libvirt-P-vnet0\n"
+ 
+ static int
+ testNWFilterEBIPTablesAllTeardown(const void *opaque G_GNUC_UNUSED)
+@@ -71,36 +71,36 @@ testNWFilterEBIPTablesAllTeardown(const void *opaque G_GNUC_UNUSED)
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+     const char *expected =
+         VIR_NWFILTER_NEW_RULES_TEARDOWN
+-        "iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
+-        "iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
+-        "iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
+-        "iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
+-        "iptables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
+-        "iptables -F FO-vnet0\n"
+-        "iptables -X FO-vnet0\n"
+-        "iptables -F FI-vnet0\n"
+-        "iptables -X FI-vnet0\n"
+-        "iptables -F HI-vnet0\n"
+-        "iptables -X HI-vnet0\n"
+-        "ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
+-        "ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
+-        "ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
+-        "ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
+-        "ip6tables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
+-        "ip6tables -F FO-vnet0\n"
+-        "ip6tables -X FO-vnet0\n"
+-        "ip6tables -F FI-vnet0\n"
+-        "ip6tables -X FI-vnet0\n"
+-        "ip6tables -F HI-vnet0\n"
+-        "ip6tables -X HI-vnet0\n"
+-        "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n"
+-        "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n"
+-        "ebtables -t nat -L libvirt-I-vnet0\n"
+-        "ebtables -t nat -L libvirt-O-vnet0\n"
+-        "ebtables -t nat -F libvirt-I-vnet0\n"
+-        "ebtables -t nat -X libvirt-I-vnet0\n"
+-        "ebtables -t nat -F libvirt-O-vnet0\n"
+-        "ebtables -t nat -X libvirt-O-vnet0\n";
++        "iptables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
++        "iptables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
++        "iptables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
++        "iptables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
++        "iptables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
++        "iptables -w -F FO-vnet0\n"
++        "iptables -w -X FO-vnet0\n"
++        "iptables -w -F FI-vnet0\n"
++        "iptables -w -X FI-vnet0\n"
++        "iptables -w -F HI-vnet0\n"
++        "iptables -w -X HI-vnet0\n"
++        "ip6tables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
++        "ip6tables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
++        "ip6tables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
++        "ip6tables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
++        "ip6tables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
++        "ip6tables -w -F FO-vnet0\n"
++        "ip6tables -w -X FO-vnet0\n"
++        "ip6tables -w -F FI-vnet0\n"
++        "ip6tables -w -X FI-vnet0\n"
++        "ip6tables -w -F HI-vnet0\n"
++        "ip6tables -w -X HI-vnet0\n"
++        "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -F libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -X libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -F libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -X libvirt-O-vnet0\n";
+     char *actual = NULL;
+     int ret = -1;
+ 
+@@ -131,44 +131,44 @@ testNWFilterEBIPTablesTearOldRules(const void *opaque G_GNUC_UNUSED)
+ {
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+     const char *expected =
+-        "iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
+-        "iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
+-        "iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
+-        "iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
+-        "iptables -F FO-vnet0\n"
+-        "iptables -X FO-vnet0\n"
+-        "iptables -F FI-vnet0\n"
+-        "iptables -X FI-vnet0\n"
+-        "iptables -F HI-vnet0\n"
+-        "iptables -X HI-vnet0\n"
+-        "iptables -E FP-vnet0 FO-vnet0\n"
+-        "iptables -E FJ-vnet0 FI-vnet0\n"
+-        "iptables -E HJ-vnet0 HI-vnet0\n"
+-        "ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
+-        "ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
+-        "ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
+-        "ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
+-        "ip6tables -F FO-vnet0\n"
+-        "ip6tables -X FO-vnet0\n"
+-        "ip6tables -F FI-vnet0\n"
+-        "ip6tables -X FI-vnet0\n"
+-        "ip6tables -F HI-vnet0\n"
+-        "ip6tables -X HI-vnet0\n"
+-        "ip6tables -E FP-vnet0 FO-vnet0\n"
+-        "ip6tables -E FJ-vnet0 FI-vnet0\n"
+-        "ip6tables -E HJ-vnet0 HI-vnet0\n"
+-        "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n"
+-        "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n"
+-        "ebtables -t nat -L libvirt-I-vnet0\n"
+-        "ebtables -t nat -L libvirt-O-vnet0\n"
+-        "ebtables -t nat -F libvirt-I-vnet0\n"
+-        "ebtables -t nat -X libvirt-I-vnet0\n"
+-        "ebtables -t nat -F libvirt-O-vnet0\n"
+-        "ebtables -t nat -X libvirt-O-vnet0\n"
+-        "ebtables -t nat -L libvirt-J-vnet0\n"
+-        "ebtables -t nat -L libvirt-P-vnet0\n"
+-        "ebtables -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n"
+-        "ebtables -t nat -E libvirt-P-vnet0 libvirt-O-vnet0\n";
++        "iptables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
++        "iptables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
++        "iptables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
++        "iptables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
++        "iptables -w -F FO-vnet0\n"
++        "iptables -w -X FO-vnet0\n"
++        "iptables -w -F FI-vnet0\n"
++        "iptables -w -X FI-vnet0\n"
++        "iptables -w -F HI-vnet0\n"
++        "iptables -w -X HI-vnet0\n"
++        "iptables -w -E FP-vnet0 FO-vnet0\n"
++        "iptables -w -E FJ-vnet0 FI-vnet0\n"
++        "iptables -w -E HJ-vnet0 HI-vnet0\n"
++        "ip6tables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
++        "ip6tables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
++        "ip6tables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
++        "ip6tables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
++        "ip6tables -w -F FO-vnet0\n"
++        "ip6tables -w -X FO-vnet0\n"
++        "ip6tables -w -F FI-vnet0\n"
++        "ip6tables -w -X FI-vnet0\n"
++        "ip6tables -w -F HI-vnet0\n"
++        "ip6tables -w -X HI-vnet0\n"
++        "ip6tables -w -E FP-vnet0 FO-vnet0\n"
++        "ip6tables -w -E FJ-vnet0 FI-vnet0\n"
++        "ip6tables -w -E HJ-vnet0 HI-vnet0\n"
++        "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -F libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -X libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -F libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -X libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-J-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-P-vnet0\n"
++        "ebtables --concurrent -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -E libvirt-P-vnet0 libvirt-O-vnet0\n";
+     char *actual = NULL;
+     int ret = -1;
+ 
+@@ -199,22 +199,22 @@ testNWFilterEBIPTablesRemoveBasicRules(const void *opaque G_GNUC_UNUSED)
+ {
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+     const char *expected =
+-        "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n"
+-        "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n"
+-        "ebtables -t nat -L libvirt-I-vnet0\n"
+-        "ebtables -t nat -L libvirt-O-vnet0\n"
+-        "ebtables -t nat -F libvirt-I-vnet0\n"
+-        "ebtables -t nat -X libvirt-I-vnet0\n"
+-        "ebtables -t nat -F libvirt-O-vnet0\n"
+-        "ebtables -t nat -X libvirt-O-vnet0\n"
+-        "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-J-vnet0\n"
+-        "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-P-vnet0\n"
+-        "ebtables -t nat -L libvirt-J-vnet0\n"
+-        "ebtables -t nat -L libvirt-P-vnet0\n"
+-        "ebtables -t nat -F libvirt-J-vnet0\n"
+-        "ebtables -t nat -X libvirt-J-vnet0\n"
+-        "ebtables -t nat -F libvirt-P-vnet0\n"
+-        "ebtables -t nat -X libvirt-P-vnet0\n";
++        "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -F libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -X libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -F libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -X libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-J-vnet0\n"
++        "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-P-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-J-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-P-vnet0\n"
++        "ebtables --concurrent -t nat -F libvirt-J-vnet0\n"
++        "ebtables --concurrent -t nat -X libvirt-J-vnet0\n"
++        "ebtables --concurrent -t nat -F libvirt-P-vnet0\n"
++        "ebtables --concurrent -t nat -X libvirt-P-vnet0\n";
+     char *actual = NULL;
+     int ret = -1;
+ 
+@@ -277,43 +277,43 @@ testNWFilterEBIPTablesApplyBasicRules(const void *opaque G_GNUC_UNUSED)
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+     const char *expected =
+         VIR_NWFILTER_NEW_RULES_TEARDOWN
+-        "iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
+-        "iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
+-        "iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
+-        "iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
+-        "iptables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
+-        "iptables -F FO-vnet0\n"
+-        "iptables -X FO-vnet0\n"
+-        "iptables -F FI-vnet0\n"
+-        "iptables -X FI-vnet0\n"
+-        "iptables -F HI-vnet0\n"
+-        "iptables -X HI-vnet0\n"
+-        "ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
+-        "ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
+-        "ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
+-        "ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
+-        "ip6tables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
+-        "ip6tables -F FO-vnet0\n"
+-        "ip6tables -X FO-vnet0\n"
+-        "ip6tables -F FI-vnet0\n"
+-        "ip6tables -X FI-vnet0\n"
+-        "ip6tables -F HI-vnet0\n"
+-        "ip6tables -X HI-vnet0\n"
+-        "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n"
+-        "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n"
+-        "ebtables -t nat -L libvirt-I-vnet0\n"
+-        "ebtables -t nat -L libvirt-O-vnet0\n"
+-        "ebtables -t nat -F libvirt-I-vnet0\n"
+-        "ebtables -t nat -X libvirt-I-vnet0\n"
+-        "ebtables -t nat -F libvirt-O-vnet0\n"
+-        "ebtables -t nat -X libvirt-O-vnet0\n"
+-        "ebtables -t nat -N libvirt-J-vnet0\n"
+-        "ebtables -t nat -A libvirt-J-vnet0 -s '!' 10:20:30:40:50:60 -j DROP\n"
+-        "ebtables -t nat -A libvirt-J-vnet0 -p IPv4 -j ACCEPT\n"
+-        "ebtables -t nat -A libvirt-J-vnet0 -p ARP -j ACCEPT\n"
+-        "ebtables -t nat -A libvirt-J-vnet0 -j DROP\n"
+-        "ebtables -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n"
+-        "ebtables -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n";
++        "iptables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
++        "iptables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
++        "iptables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
++        "iptables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
++        "iptables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
++        "iptables -w -F FO-vnet0\n"
++        "iptables -w -X FO-vnet0\n"
++        "iptables -w -F FI-vnet0\n"
++        "iptables -w -X FI-vnet0\n"
++        "iptables -w -F HI-vnet0\n"
++        "iptables -w -X HI-vnet0\n"
++        "ip6tables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
++        "ip6tables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
++        "ip6tables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
++        "ip6tables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
++        "ip6tables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
++        "ip6tables -w -F FO-vnet0\n"
++        "ip6tables -w -X FO-vnet0\n"
++        "ip6tables -w -F FI-vnet0\n"
++        "ip6tables -w -X FI-vnet0\n"
++        "ip6tables -w -F HI-vnet0\n"
++        "ip6tables -w -X HI-vnet0\n"
++        "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -F libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -X libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -F libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -X libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -N libvirt-J-vnet0\n"
++        "ebtables --concurrent -t nat -A libvirt-J-vnet0 -s '!' 10:20:30:40:50:60 -j DROP\n"
++        "ebtables --concurrent -t nat -A libvirt-J-vnet0 -p IPv4 -j ACCEPT\n"
++        "ebtables --concurrent -t nat -A libvirt-J-vnet0 -p ARP -j ACCEPT\n"
++        "ebtables --concurrent -t nat -A libvirt-J-vnet0 -j DROP\n"
++        "ebtables --concurrent -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n"
++        "ebtables --concurrent -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n";
+     char *actual = NULL;
+     int ret = -1;
+     virMacAddr mac = { .addr = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 } };
+@@ -346,51 +346,51 @@ testNWFilterEBIPTablesApplyDHCPOnlyRules(const void *opaque G_GNUC_UNUSED)
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+     const char *expected =
+         VIR_NWFILTER_NEW_RULES_TEARDOWN
+-        "iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
+-        "iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
+-        "iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
+-        "iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
+-        "iptables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
+-        "iptables -F FO-vnet0\n"
+-        "iptables -X FO-vnet0\n"
+-        "iptables -F FI-vnet0\n"
+-        "iptables -X FI-vnet0\n"
+-        "iptables -F HI-vnet0\n"
+-        "iptables -X HI-vnet0\n"
+-        "ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
+-        "ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
+-        "ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
+-        "ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
+-        "ip6tables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
+-        "ip6tables -F FO-vnet0\n"
+-        "ip6tables -X FO-vnet0\n"
+-        "ip6tables -F FI-vnet0\n"
+-        "ip6tables -X FI-vnet0\n"
+-        "ip6tables -F HI-vnet0\n"
+-        "ip6tables -X HI-vnet0\n"
+-        "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n"
+-        "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n"
+-        "ebtables -t nat -L libvirt-I-vnet0\n"
+-        "ebtables -t nat -L libvirt-O-vnet0\n"
+-        "ebtables -t nat -F libvirt-I-vnet0\n"
+-        "ebtables -t nat -X libvirt-I-vnet0\n"
+-        "ebtables -t nat -F libvirt-O-vnet0\n"
+-        "ebtables -t nat -X libvirt-O-vnet0\n"
+-        "ebtables -t nat -N libvirt-J-vnet0\n"
+-        "ebtables -t nat -N libvirt-P-vnet0\n"
+-        "ebtables -t nat -A libvirt-J-vnet0 -s 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-sport 68 --ip-dport 67 -j ACCEPT\n"
+-        "ebtables -t nat -A libvirt-J-vnet0 -j DROP\n"
+-        "ebtables -t nat -A libvirt-P-vnet0 -d 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-src 192.168.122.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n"
+-        "ebtables -t nat -A libvirt-P-vnet0 -d ff:ff:ff:ff:ff:ff -p ipv4 --ip-protocol udp --ip-src 192.168.122.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n"
+-        "ebtables -t nat -A libvirt-P-vnet0 -d 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-src 10.0.0.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n"
+-        "ebtables -t nat -A libvirt-P-vnet0 -d ff:ff:ff:ff:ff:ff -p ipv4 --ip-protocol udp --ip-src 10.0.0.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n"
+-        "ebtables -t nat -A libvirt-P-vnet0 -d 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-src 10.0.0.2 --ip-sport 67 --ip-dport 68 -j ACCEPT\n"
+-        "ebtables -t nat -A libvirt-P-vnet0 -d ff:ff:ff:ff:ff:ff -p ipv4 --ip-protocol udp --ip-src 10.0.0.2 --ip-sport 67 --ip-dport 68 -j ACCEPT\n"
+-        "ebtables -t nat -A libvirt-P-vnet0 -j DROP\n"
+-        "ebtables -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n"
+-        "ebtables -t nat -A POSTROUTING -o vnet0 -j libvirt-P-vnet0\n"
+-        "ebtables -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n"
+-        "ebtables -t nat -E libvirt-P-vnet0 libvirt-O-vnet0\n";
++        "iptables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
++        "iptables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
++        "iptables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
++        "iptables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
++        "iptables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
++        "iptables -w -F FO-vnet0\n"
++        "iptables -w -X FO-vnet0\n"
++        "iptables -w -F FI-vnet0\n"
++        "iptables -w -X FI-vnet0\n"
++        "iptables -w -F HI-vnet0\n"
++        "iptables -w -X HI-vnet0\n"
++        "ip6tables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
++        "ip6tables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
++        "ip6tables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
++        "ip6tables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
++        "ip6tables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
++        "ip6tables -w -F FO-vnet0\n"
++        "ip6tables -w -X FO-vnet0\n"
++        "ip6tables -w -F FI-vnet0\n"
++        "ip6tables -w -X FI-vnet0\n"
++        "ip6tables -w -F HI-vnet0\n"
++        "ip6tables -w -X HI-vnet0\n"
++        "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -F libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -X libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -F libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -X libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -N libvirt-J-vnet0\n"
++        "ebtables --concurrent -t nat -N libvirt-P-vnet0\n"
++        "ebtables --concurrent -t nat -A libvirt-J-vnet0 -s 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-sport 68 --ip-dport 67 -j ACCEPT\n"
++        "ebtables --concurrent -t nat -A libvirt-J-vnet0 -j DROP\n"
++        "ebtables --concurrent -t nat -A libvirt-P-vnet0 -d 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-src 192.168.122.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n"
++        "ebtables --concurrent -t nat -A libvirt-P-vnet0 -d ff:ff:ff:ff:ff:ff -p ipv4 --ip-protocol udp --ip-src 192.168.122.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n"
++        "ebtables --concurrent -t nat -A libvirt-P-vnet0 -d 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-src 10.0.0.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n"
++        "ebtables --concurrent -t nat -A libvirt-P-vnet0 -d ff:ff:ff:ff:ff:ff -p ipv4 --ip-protocol udp --ip-src 10.0.0.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n"
++        "ebtables --concurrent -t nat -A libvirt-P-vnet0 -d 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-src 10.0.0.2 --ip-sport 67 --ip-dport 68 -j ACCEPT\n"
++        "ebtables --concurrent -t nat -A libvirt-P-vnet0 -d ff:ff:ff:ff:ff:ff -p ipv4 --ip-protocol udp --ip-src 10.0.0.2 --ip-sport 67 --ip-dport 68 -j ACCEPT\n"
++        "ebtables --concurrent -t nat -A libvirt-P-vnet0 -j DROP\n"
++        "ebtables --concurrent -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n"
++        "ebtables --concurrent -t nat -A POSTROUTING -o vnet0 -j libvirt-P-vnet0\n"
++        "ebtables --concurrent -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -E libvirt-P-vnet0 libvirt-O-vnet0\n";
+     char *actual = NULL;
+     int ret = -1;
+     virMacAddr mac = { .addr = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 } };
+@@ -434,44 +434,44 @@ testNWFilterEBIPTablesApplyDropAllRules(const void *opaque G_GNUC_UNUSED)
+     virBuffer buf = VIR_BUFFER_INITIALIZER;
+     const char *expected =
+         VIR_NWFILTER_NEW_RULES_TEARDOWN
+-        "iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
+-        "iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
+-        "iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
+-        "iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
+-        "iptables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
+-        "iptables -F FO-vnet0\n"
+-        "iptables -X FO-vnet0\n"
+-        "iptables -F FI-vnet0\n"
+-        "iptables -X FI-vnet0\n"
+-        "iptables -F HI-vnet0\n"
+-        "iptables -X HI-vnet0\n"
+-        "ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
+-        "ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
+-        "ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
+-        "ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
+-        "ip6tables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
+-        "ip6tables -F FO-vnet0\n"
+-        "ip6tables -X FO-vnet0\n"
+-        "ip6tables -F FI-vnet0\n"
+-        "ip6tables -X FI-vnet0\n"
+-        "ip6tables -F HI-vnet0\n"
+-        "ip6tables -X HI-vnet0\n"
+-        "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n"
+-        "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n"
+-        "ebtables -t nat -L libvirt-I-vnet0\n"
+-        "ebtables -t nat -L libvirt-O-vnet0\n"
+-        "ebtables -t nat -F libvirt-I-vnet0\n"
+-        "ebtables -t nat -X libvirt-I-vnet0\n"
+-        "ebtables -t nat -F libvirt-O-vnet0\n"
+-        "ebtables -t nat -X libvirt-O-vnet0\n"
+-        "ebtables -t nat -N libvirt-J-vnet0\n"
+-        "ebtables -t nat -N libvirt-P-vnet0\n"
+-        "ebtables -t nat -A libvirt-J-vnet0 -j DROP\n"
+-        "ebtables -t nat -A libvirt-P-vnet0 -j DROP\n"
+-        "ebtables -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n"
+-        "ebtables -t nat -A POSTROUTING -o vnet0 -j libvirt-P-vnet0\n"
+-        "ebtables -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n"
+-        "ebtables -t nat -E libvirt-P-vnet0 libvirt-O-vnet0\n";
++        "iptables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
++        "iptables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
++        "iptables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
++        "iptables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
++        "iptables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
++        "iptables -w -F FO-vnet0\n"
++        "iptables -w -X FO-vnet0\n"
++        "iptables -w -F FI-vnet0\n"
++        "iptables -w -X FI-vnet0\n"
++        "iptables -w -F HI-vnet0\n"
++        "iptables -w -X HI-vnet0\n"
++        "ip6tables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n"
++        "ip6tables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n"
++        "ip6tables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n"
++        "ip6tables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n"
++        "ip6tables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
++        "ip6tables -w -F FO-vnet0\n"
++        "ip6tables -w -X FO-vnet0\n"
++        "ip6tables -w -F FI-vnet0\n"
++        "ip6tables -w -X FI-vnet0\n"
++        "ip6tables -w -F HI-vnet0\n"
++        "ip6tables -w -X HI-vnet0\n"
++        "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -L libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -F libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -X libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -F libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -X libvirt-O-vnet0\n"
++        "ebtables --concurrent -t nat -N libvirt-J-vnet0\n"
++        "ebtables --concurrent -t nat -N libvirt-P-vnet0\n"
++        "ebtables --concurrent -t nat -A libvirt-J-vnet0 -j DROP\n"
++        "ebtables --concurrent -t nat -A libvirt-P-vnet0 -j DROP\n"
++        "ebtables --concurrent -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n"
++        "ebtables --concurrent -t nat -A POSTROUTING -o vnet0 -j libvirt-P-vnet0\n"
++        "ebtables --concurrent -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n"
++        "ebtables --concurrent -t nat -E libvirt-P-vnet0 libvirt-O-vnet0\n";
+     char *actual = NULL;
+     int ret = -1;
+ 
+diff --git a/tests/nwfilterxml2firewalldata/ah-ipv6-linux.args b/tests/nwfilterxml2firewalldata/ah-ipv6-linux.args
+index 35c9de38b8..77f0532fd2 100644
+--- a/tests/nwfilterxml2firewalldata/ah-ipv6-linux.args
++++ b/tests/nwfilterxml2firewalldata/ah-ipv6-linux.args
+@@ -1,4 +1,5 @@
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p ah \
+ -m mac \
+@@ -11,6 +12,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p ah \
+ --destination f:e:d::c:b:a/127 \
+@@ -21,6 +23,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p ah \
+ -m mac \
+@@ -33,6 +36,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p ah \
+ --destination a:b:c::/128 \
+@@ -42,6 +46,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p ah \
+ -m mac \
+@@ -53,6 +58,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p ah \
+ --destination a:b:c::/128 \
+@@ -62,6 +68,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p ah \
+ --destination ::10.1.2.3/128 \
+@@ -71,6 +78,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p ah \
+ -m mac \
+@@ -82,6 +90,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p ah \
+ --destination ::10.1.2.3/128 \
+diff --git a/tests/nwfilterxml2firewalldata/ah-linux.args b/tests/nwfilterxml2firewalldata/ah-linux.args
+index 269636754e..c7e5c1eb17 100644
+--- a/tests/nwfilterxml2firewalldata/ah-linux.args
++++ b/tests/nwfilterxml2firewalldata/ah-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p ah \
+ -m mac \
+@@ -10,6 +11,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p ah \
+ --source 10.1.2.3/32 \
+@@ -19,6 +21,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p ah \
+ -m mac \
+@@ -30,6 +33,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p ah \
+ --destination 10.1.2.3/22 \
+@@ -39,6 +43,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p ah \
+ -m mac \
+@@ -50,6 +55,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p ah \
+ --destination 10.1.2.3/22 \
+@@ -59,6 +65,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p ah \
+ --destination 10.1.2.3/22 \
+@@ -68,6 +75,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p ah \
+ -m mac \
+@@ -79,6 +87,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p ah \
+ --destination 10.1.2.3/22 \
+diff --git a/tests/nwfilterxml2firewalldata/all-ipv6-linux.args b/tests/nwfilterxml2firewalldata/all-ipv6-linux.args
+index 2f84c1bfea..d86908663c 100644
+--- a/tests/nwfilterxml2firewalldata/all-ipv6-linux.args
++++ b/tests/nwfilterxml2firewalldata/all-ipv6-linux.args
+@@ -1,4 +1,5 @@
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m mac \
+@@ -11,6 +12,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ --destination f:e:d::c:b:a/127 \
+@@ -21,6 +23,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m mac \
+@@ -33,6 +36,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ --destination a:b:c::/128 \
+@@ -42,6 +46,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m mac \
+@@ -53,6 +58,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ --destination a:b:c::/128 \
+@@ -62,6 +68,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ --destination ::10.1.2.3/128 \
+@@ -71,6 +78,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m mac \
+@@ -82,6 +90,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ --destination ::10.1.2.3/128 \
+diff --git a/tests/nwfilterxml2firewalldata/all-linux.args b/tests/nwfilterxml2firewalldata/all-linux.args
+index 7ea769f74f..187d9ed9ca 100644
+--- a/tests/nwfilterxml2firewalldata/all-linux.args
++++ b/tests/nwfilterxml2firewalldata/all-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m mac \
+@@ -10,6 +11,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ --source 10.1.2.3/32 \
+@@ -19,6 +21,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m mac \
+@@ -30,6 +33,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ --destination 10.1.2.3/22 \
+@@ -39,6 +43,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m mac \
+@@ -50,6 +55,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ --destination 10.1.2.3/22 \
+@@ -59,6 +65,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ --destination 10.1.2.3/22 \
+@@ -68,6 +75,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m mac \
+@@ -79,6 +87,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ --destination 10.1.2.3/22 \
+diff --git a/tests/nwfilterxml2firewalldata/arp-linux.args b/tests/nwfilterxml2firewalldata/arp-linux.args
+index b1360175c4..ef9f44d7bb 100644
+--- a/tests/nwfilterxml2firewalldata/arp-linux.args
++++ b/tests/nwfilterxml2firewalldata/arp-linux.args
+@@ -1,4 +1,5 @@
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -11,6 +12,7 @@ ebtables \
+ --arp-mac-dst 0a:0b:0c:0d:0e:0f \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -20,6 +22,7 @@ ebtables \
+ --arp-ptype 0xff \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -29,6 +32,7 @@ ebtables \
+ --arp-ptype 0x100 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -38,6 +42,7 @@ ebtables \
+ --arp-ptype 0xffff \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -p 0x806 \
+diff --git a/tests/nwfilterxml2firewalldata/comment-linux.args b/tests/nwfilterxml2firewalldata/comment-linux.args
+index 462b2e2177..6233ccf9f5 100644
+--- a/tests/nwfilterxml2firewalldata/comment-linux.args
++++ b/tests/nwfilterxml2firewalldata/comment-linux.args
+@@ -1,9 +1,11 @@
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -p 0x1234 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -17,6 +19,7 @@ ebtables \
+ --ip-tos 0x32 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:fe \
+@@ -29,6 +32,7 @@ ebtables \
+ --ip6-destination-port 13107:65535 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -41,6 +45,7 @@ ebtables \
+ --arp-mac-dst 0a:0b:0c:0d:0e:0f \
+ -j ACCEPT
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ -m mac \
+@@ -56,6 +61,7 @@ iptables \
+ --comment 'udp rule' \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --source 10.1.2.3/32 \
+@@ -69,6 +75,7 @@ iptables \
+ --comment 'udp rule' \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ -m mac \
+@@ -84,6 +91,7 @@ iptables \
+ --comment 'udp rule' \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --destination a:b:c::/128 \
+@@ -97,6 +105,7 @@ ip6tables \
+ --comment 'tcp/ipv6 rule' \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ -m mac \
+@@ -112,6 +121,7 @@ ip6tables \
+ --comment 'tcp/ipv6 rule' \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --destination a:b:c::/128 \
+@@ -125,6 +135,7 @@ ip6tables \
+ --comment 'tcp/ipv6 rule' \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ -m state \
+@@ -133,6 +144,7 @@ ip6tables \
+ --comment '`ls`;${COLUMNS};$(ls);"test";&'\''3   spaces'\''' \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ -m state \
+@@ -141,6 +153,7 @@ ip6tables \
+ --comment '`ls`;${COLUMNS};$(ls);"test";&'\''3   spaces'\''' \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ -m state \
+@@ -149,6 +162,7 @@ ip6tables \
+ --comment '`ls`;${COLUMNS};$(ls);"test";&'\''3   spaces'\''' \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ -m state \
+@@ -157,6 +171,7 @@ ip6tables \
+ --comment 'comment with lone '\'', `, ", `, \, $x, and two  spaces' \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ -m state \
+@@ -165,6 +180,7 @@ ip6tables \
+ --comment 'comment with lone '\'', `, ", `, \, $x, and two  spaces' \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ -m state \
+@@ -173,6 +189,7 @@ ip6tables \
+ --comment 'comment with lone '\'', `, ", `, \, $x, and two  spaces' \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p ah \
+ -m state \
+@@ -182,6 +199,7 @@ ip6tables \
+ -f ${tmp}' \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p ah \
+ -m state \
+@@ -191,6 +209,7 @@ ip6tables \
+ -f ${tmp}' \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p ah \
+ -m state \
+diff --git a/tests/nwfilterxml2firewalldata/conntrack-linux.args b/tests/nwfilterxml2firewalldata/conntrack-linux.args
+index c653049e8e..78495598a1 100644
+--- a/tests/nwfilterxml2firewalldata/conntrack-linux.args
++++ b/tests/nwfilterxml2firewalldata/conntrack-linux.args
+@@ -1,40 +1,47 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p icmp \
+ -m connlimit \
+ --connlimit-above 1 \
+ -j DROP
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p icmp \
+ -m connlimit \
+ --connlimit-above 1 \
+ -j DROP
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ -m connlimit \
+ --connlimit-above 2 \
+ -j DROP
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ -m connlimit \
+ --connlimit-above 2 \
+ -j DROP
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m state \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m state \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m state \
+diff --git a/tests/nwfilterxml2firewalldata/esp-ipv6-linux.args b/tests/nwfilterxml2firewalldata/esp-ipv6-linux.args
+index 51cf74815b..22dad0b412 100644
+--- a/tests/nwfilterxml2firewalldata/esp-ipv6-linux.args
++++ b/tests/nwfilterxml2firewalldata/esp-ipv6-linux.args
+@@ -1,4 +1,5 @@
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p esp \
+ -m mac \
+@@ -11,6 +12,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p esp \
+ --destination f:e:d::c:b:a/127 \
+@@ -21,6 +23,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p esp \
+ -m mac \
+@@ -33,6 +36,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p esp \
+ --destination a:b:c::/128 \
+@@ -42,6 +46,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p esp \
+ -m mac \
+@@ -53,6 +58,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p esp \
+ --destination a:b:c::/128 \
+@@ -62,6 +68,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p esp \
+ --destination ::10.1.2.3/128 \
+@@ -71,6 +78,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p esp \
+ -m mac \
+@@ -82,6 +90,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p esp \
+ --destination ::10.1.2.3/128 \
+diff --git a/tests/nwfilterxml2firewalldata/esp-linux.args b/tests/nwfilterxml2firewalldata/esp-linux.args
+index 17acb8133c..7cd70afaa1 100644
+--- a/tests/nwfilterxml2firewalldata/esp-linux.args
++++ b/tests/nwfilterxml2firewalldata/esp-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p esp \
+ -m mac \
+@@ -10,6 +11,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p esp \
+ --source 10.1.2.3/32 \
+@@ -19,6 +21,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p esp \
+ -m mac \
+@@ -30,6 +33,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p esp \
+ --destination 10.1.2.3/22 \
+@@ -39,6 +43,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p esp \
+ -m mac \
+@@ -50,6 +55,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p esp \
+ --destination 10.1.2.3/22 \
+@@ -59,6 +65,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p esp \
+ --destination 10.1.2.3/22 \
+@@ -68,6 +75,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p esp \
+ -m mac \
+@@ -79,6 +87,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p esp \
+ --destination 10.1.2.3/22 \
+diff --git a/tests/nwfilterxml2firewalldata/example-1-linux.args b/tests/nwfilterxml2firewalldata/example-1-linux.args
+index c5549f8dd6..1cc3746d40 100644
+--- a/tests/nwfilterxml2firewalldata/example-1-linux.args
++++ b/tests/nwfilterxml2firewalldata/example-1-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --sport 22 \
+@@ -6,6 +7,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --dport 22 \
+@@ -13,6 +15,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --sport 22 \
+@@ -20,50 +23,59 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p icmp \
+ -m state \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p icmp \
+ -m state \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p icmp \
+ -m state \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m state \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m state \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m state \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -j DROP
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -j DROP
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -j DROP
+diff --git a/tests/nwfilterxml2firewalldata/example-2-linux.args b/tests/nwfilterxml2firewalldata/example-2-linux.args
+index 2db58f1e0f..87462ad954 100644
+--- a/tests/nwfilterxml2firewalldata/example-2-linux.args
++++ b/tests/nwfilterxml2firewalldata/example-2-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m state \
+@@ -7,6 +8,7 @@ iptables \
+ --comment 'out: existing and related (ftp) connections' \
+ -j RETURN
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m state \
+@@ -15,6 +17,7 @@ iptables \
+ --comment 'out: existing and related (ftp) connections' \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m state \
+@@ -23,6 +26,7 @@ iptables \
+ --comment 'in: existing connections' \
+ -j ACCEPT
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --dport 21:22 \
+@@ -32,6 +36,7 @@ iptables \
+ --comment 'in: ftp and ssh' \
+ -j ACCEPT
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p icmp \
+ -m state \
+@@ -40,6 +45,7 @@ iptables \
+ --comment 'in: icmp' \
+ -j ACCEPT
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --dport 53 \
+@@ -49,6 +55,7 @@ iptables \
+ --comment 'out: DNS lookups' \
+ -j RETURN
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --dport 53 \
+@@ -58,18 +65,21 @@ iptables \
+ --comment 'out: DNS lookups' \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m comment \
+ --comment 'inout: drop all non-accepted traffic' \
+ -j DROP
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m comment \
+ --comment 'inout: drop all non-accepted traffic' \
+ -j DROP
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m comment \
+diff --git a/tests/nwfilterxml2firewalldata/hex-data-linux.args b/tests/nwfilterxml2firewalldata/hex-data-linux.args
+index f1a1f588f2..3c04e1c23d 100644
+--- a/tests/nwfilterxml2firewalldata/hex-data-linux.args
++++ b/tests/nwfilterxml2firewalldata/hex-data-linux.args
+@@ -1,9 +1,11 @@
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -p 0x1234 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -17,6 +19,7 @@ ebtables \
+ --ip-tos 0x32 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:fe \
+@@ -29,6 +32,7 @@ ebtables \
+ --ip6-destination-port 13107:65535 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -41,6 +45,7 @@ ebtables \
+ --arp-mac-dst 0a:0b:0c:0d:0e:0f \
+ -j ACCEPT
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ -m mac \
+@@ -54,6 +59,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --source 10.1.2.3/32 \
+@@ -65,6 +71,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ -m mac \
+@@ -78,6 +85,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --destination a:b:c::/128 \
+@@ -89,6 +97,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ -m mac \
+@@ -102,6 +111,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --destination a:b:c::/128 \
+diff --git a/tests/nwfilterxml2firewalldata/icmp-direction-linux.args b/tests/nwfilterxml2firewalldata/icmp-direction-linux.args
+index 9f481fa831..7548aaeba5 100644
+--- a/tests/nwfilterxml2firewalldata/icmp-direction-linux.args
++++ b/tests/nwfilterxml2firewalldata/icmp-direction-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p icmp \
+ --icmp-type 0 \
+@@ -6,6 +7,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p icmp \
+ --icmp-type 8 \
+@@ -13,6 +15,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p icmp \
+ --icmp-type 8 \
+@@ -20,14 +23,17 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p icmp \
+ -j DROP
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p icmp \
+ -j DROP
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p icmp \
+ -j DROP
+diff --git a/tests/nwfilterxml2firewalldata/icmp-direction2-linux.args b/tests/nwfilterxml2firewalldata/icmp-direction2-linux.args
+index 1faa3d880a..026702caee 100644
+--- a/tests/nwfilterxml2firewalldata/icmp-direction2-linux.args
++++ b/tests/nwfilterxml2firewalldata/icmp-direction2-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p icmp \
+ --icmp-type 8 \
+@@ -6,6 +7,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p icmp \
+ --icmp-type 0 \
+@@ -13,6 +15,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p icmp \
+ --icmp-type 0 \
+@@ -20,14 +23,17 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p icmp \
+ -j DROP
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p icmp \
+ -j DROP
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p icmp \
+ -j DROP
+diff --git a/tests/nwfilterxml2firewalldata/icmp-direction3-linux.args b/tests/nwfilterxml2firewalldata/icmp-direction3-linux.args
+index 6cc8e132d9..6ee6a4f84a 100644
+--- a/tests/nwfilterxml2firewalldata/icmp-direction3-linux.args
++++ b/tests/nwfilterxml2firewalldata/icmp-direction3-linux.args
+@@ -1,30 +1,36 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p icmp \
+ -m state \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p icmp \
+ -m state \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p icmp \
+ -m state \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -j DROP
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -j DROP
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -j DROP
+diff --git a/tests/nwfilterxml2firewalldata/icmp-linux.args b/tests/nwfilterxml2firewalldata/icmp-linux.args
+index d808f0ea60..d688e29213 100644
+--- a/tests/nwfilterxml2firewalldata/icmp-linux.args
++++ b/tests/nwfilterxml2firewalldata/icmp-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p icmp \
+ -m mac \
+@@ -11,6 +12,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p icmp \
+ -m mac \
+@@ -23,6 +25,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p icmp \
+ -m mac \
+diff --git a/tests/nwfilterxml2firewalldata/icmpv6-linux.args b/tests/nwfilterxml2firewalldata/icmpv6-linux.args
+index 92190eb311..6e2110fb81 100644
+--- a/tests/nwfilterxml2firewalldata/icmpv6-linux.args
++++ b/tests/nwfilterxml2firewalldata/icmpv6-linux.args
+@@ -1,4 +1,5 @@
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p icmpv6 \
+ -m mac \
+@@ -12,6 +13,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p icmpv6 \
+ -m mac \
+@@ -25,6 +27,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p icmpv6 \
+ -m mac \
+@@ -37,6 +40,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p icmpv6 \
+ -m mac \
+diff --git a/tests/nwfilterxml2firewalldata/igmp-linux.args b/tests/nwfilterxml2firewalldata/igmp-linux.args
+index 727463a62d..b954b0ae99 100644
+--- a/tests/nwfilterxml2firewalldata/igmp-linux.args
++++ b/tests/nwfilterxml2firewalldata/igmp-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p igmp \
+ -m mac \
+@@ -10,6 +11,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p igmp \
+ --source 10.1.2.3/32 \
+@@ -19,6 +21,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p igmp \
+ -m mac \
+@@ -30,6 +33,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p igmp \
+ --destination 10.1.2.3/22 \
+@@ -39,6 +43,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p igmp \
+ -m mac \
+@@ -50,6 +55,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p igmp \
+ --destination 10.1.2.3/22 \
+@@ -59,6 +65,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p igmp \
+ --destination 10.1.2.3/22 \
+@@ -68,6 +75,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p igmp \
+ -m mac \
+@@ -79,6 +87,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p igmp \
+ --destination 10.1.2.3/22 \
+diff --git a/tests/nwfilterxml2firewalldata/ip-linux.args b/tests/nwfilterxml2firewalldata/ip-linux.args
+index 399a47491e..8e64839678 100644
+--- a/tests/nwfilterxml2firewalldata/ip-linux.args
++++ b/tests/nwfilterxml2firewalldata/ip-linux.args
+@@ -1,4 +1,5 @@
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -11,6 +12,7 @@ ebtables \
+ --ip-destination-port 100:101 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -p ipv4 \
+@@ -20,6 +22,7 @@ ebtables \
+ --ip-tos 0x3f \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -p ipv4 \
+diff --git a/tests/nwfilterxml2firewalldata/ipset-linux.args b/tests/nwfilterxml2firewalldata/ipset-linux.args
+index 0fe0739962..5cdb151354 100644
+--- a/tests/nwfilterxml2firewalldata/ipset-linux.args
++++ b/tests/nwfilterxml2firewalldata/ipset-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m state \
+@@ -7,6 +8,7 @@ iptables \
+ --match-set tck_test src,dst \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m state \
+@@ -15,6 +17,7 @@ iptables \
+ --match-set tck_test dst,src \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m state \
+@@ -23,6 +26,7 @@ iptables \
+ --match-set tck_test src,dst \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m set \
+@@ -31,6 +35,7 @@ iptables \
+ --comment in+NONE \
+ -j ACCEPT
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m set \
+@@ -39,6 +44,7 @@ iptables \
+ --comment out+NONE \
+ -j RETURN
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m set \
+@@ -47,6 +53,7 @@ iptables \
+ --comment out+NONE \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m state \
+@@ -55,6 +62,7 @@ iptables \
+ --match-set tck_test dst,src,dst \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m state \
+@@ -63,6 +71,7 @@ iptables \
+ --match-set tck_test src,dst,src \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m state \
+@@ -71,6 +80,7 @@ iptables \
+ --match-set tck_test dst,src,dst \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m state \
+@@ -79,6 +89,7 @@ iptables \
+ --match-set tck_test dst,src,dst \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m state \
+@@ -87,6 +98,7 @@ iptables \
+ --match-set tck_test src,dst,src \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m state \
+@@ -95,6 +107,7 @@ iptables \
+ --match-set tck_test dst,src,dst \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m state \
+@@ -103,6 +116,7 @@ iptables \
+ --match-set tck_test dst,src \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m state \
+@@ -111,6 +125,7 @@ iptables \
+ --match-set tck_test src,dst \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m state \
+@@ -119,6 +134,7 @@ iptables \
+ --match-set tck_test dst,src \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m set \
+@@ -127,6 +143,7 @@ iptables \
+ --comment inout \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m set \
+@@ -135,6 +152,7 @@ iptables \
+ --comment inout \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m set \
+diff --git a/tests/nwfilterxml2firewalldata/ipt-no-macspoof-linux.args b/tests/nwfilterxml2firewalldata/ipt-no-macspoof-linux.args
+index 86ab228fb8..c35fa1e488 100644
+--- a/tests/nwfilterxml2firewalldata/ipt-no-macspoof-linux.args
++++ b/tests/nwfilterxml2firewalldata/ipt-no-macspoof-linux.args
+@@ -1,10 +1,12 @@
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m mac '!' \
+ --mac-source 12:34:56:78:9a:bc \
+ -j DROP
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m mac '!' \
+diff --git a/tests/nwfilterxml2firewalldata/ipv6-linux.args b/tests/nwfilterxml2firewalldata/ipv6-linux.args
+index 6fba19f2eb..87db9c2979 100644
+--- a/tests/nwfilterxml2firewalldata/ipv6-linux.args
++++ b/tests/nwfilterxml2firewalldata/ipv6-linux.args
+@@ -1,4 +1,5 @@
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:fe \
+@@ -11,6 +12,7 @@ ebtables \
+ --ip6-destination-port 100:101 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -p ipv6 \
+@@ -21,6 +23,7 @@ ebtables \
+ --ip6-source-port 100:101 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -p ipv6 \
+@@ -31,6 +34,7 @@ ebtables \
+ --ip6-destination-port 100:101 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -p ipv6 \
+@@ -41,6 +45,7 @@ ebtables \
+ --ip6-source-port 65535:65535 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -p ipv6 \
+@@ -51,6 +56,7 @@ ebtables \
+ --ip6-destination-port 65535:65535 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -p ipv6 \
+@@ -59,6 +65,7 @@ ebtables \
+ --ip6-protocol 18 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -p ipv6 \
+@@ -67,6 +74,7 @@ ebtables \
+ --ip6-protocol 18 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -p ipv6 \
+@@ -76,6 +84,7 @@ ebtables \
+ --ip6-icmp-type 1:11/10:11 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -p ipv6 \
+@@ -85,6 +94,7 @@ ebtables \
+ --ip6-icmp-type 1:11/10:11 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -p ipv6 \
+@@ -94,6 +104,7 @@ ebtables \
+ --ip6-icmp-type 1:1/10:10 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -p ipv6 \
+@@ -103,6 +114,7 @@ ebtables \
+ --ip6-icmp-type 1:1/10:10 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -p ipv6 \
+@@ -112,6 +124,7 @@ ebtables \
+ --ip6-icmp-type 0:255/10:10 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -p ipv6 \
+@@ -121,6 +134,7 @@ ebtables \
+ --ip6-icmp-type 0:255/10:10 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -p ipv6 \
+@@ -130,6 +144,7 @@ ebtables \
+ --ip6-icmp-type 1:1/0:255 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -p ipv6 \
+diff --git a/tests/nwfilterxml2firewalldata/iter1-linux.args b/tests/nwfilterxml2firewalldata/iter1-linux.args
+index 31f37cf537..9bdad18748 100644
+--- a/tests/nwfilterxml2firewalldata/iter1-linux.args
++++ b/tests/nwfilterxml2firewalldata/iter1-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -9,6 +10,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 1.1.1.1 \
+@@ -19,6 +21,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -29,6 +32,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -39,6 +43,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 2.2.2.2 \
+@@ -49,6 +54,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -59,6 +65,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -69,6 +76,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 3.3.3.3 \
+@@ -79,6 +87,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+diff --git a/tests/nwfilterxml2firewalldata/iter2-linux.args b/tests/nwfilterxml2firewalldata/iter2-linux.args
+index 4230a9d524..b088350ee5 100644
+--- a/tests/nwfilterxml2firewalldata/iter2-linux.args
++++ b/tests/nwfilterxml2firewalldata/iter2-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -9,6 +10,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 1.1.1.1 \
+@@ -19,6 +21,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -29,6 +32,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -39,6 +43,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 2.2.2.2 \
+@@ -49,6 +54,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -59,6 +65,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -69,6 +76,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 3.3.3.3 \
+@@ -79,6 +87,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -89,6 +98,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 1.1.1.1 \
+@@ -99,6 +109,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 1.1.1.1 \
+@@ -109,6 +120,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 1.1.1.1 \
+@@ -119,6 +131,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 2.2.2.2 \
+@@ -129,6 +142,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 2.2.2.2 \
+@@ -139,6 +153,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 2.2.2.2 \
+@@ -149,6 +164,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 3.3.3.3 \
+@@ -159,6 +175,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 3.3.3.3 \
+@@ -169,6 +186,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 3.3.3.3 \
+@@ -179,6 +197,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 1.1.1.1 \
+@@ -189,6 +208,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 1.1.1.1 \
+@@ -199,6 +219,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 1.1.1.1 \
+@@ -209,6 +230,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 2.2.2.2 \
+@@ -219,6 +241,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 2.2.2.2 \
+@@ -229,6 +252,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 2.2.2.2 \
+@@ -239,6 +263,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 3.3.3.3 \
+@@ -249,6 +274,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 3.3.3.3 \
+@@ -259,6 +285,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 3.3.3.3 \
+@@ -269,6 +296,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 1.1.1.1 \
+@@ -280,6 +308,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 1.1.1.1 \
+@@ -291,6 +320,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 1.1.1.1 \
+@@ -302,6 +332,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 2.2.2.2 \
+@@ -313,6 +344,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 2.2.2.2 \
+@@ -324,6 +356,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 2.2.2.2 \
+@@ -335,6 +368,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 3.3.3.3 \
+@@ -346,6 +380,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 3.3.3.3 \
+@@ -357,6 +392,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 3.3.3.3 \
+@@ -368,6 +404,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 1.1.1.1 \
+@@ -379,6 +416,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 1.1.1.1 \
+@@ -390,6 +428,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 1.1.1.1 \
+@@ -401,6 +440,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 2.2.2.2 \
+@@ -412,6 +452,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 2.2.2.2 \
+@@ -423,6 +464,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 2.2.2.2 \
+@@ -434,6 +476,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 3.3.3.3 \
+@@ -445,6 +488,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 3.3.3.3 \
+@@ -456,6 +500,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 3.3.3.3 \
+@@ -467,6 +512,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 1.1.1.1 \
+@@ -478,6 +524,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 1.1.1.1 \
+@@ -489,6 +536,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 1.1.1.1 \
+@@ -500,6 +548,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 2.2.2.2 \
+@@ -511,6 +560,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 2.2.2.2 \
+@@ -522,6 +572,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 2.2.2.2 \
+@@ -533,6 +584,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 3.3.3.3 \
+@@ -544,6 +596,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 3.3.3.3 \
+@@ -555,6 +608,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 3.3.3.3 \
+@@ -566,6 +620,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 1.1.1.1 \
+@@ -577,6 +632,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 1.1.1.1 \
+@@ -588,6 +644,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 1.1.1.1 \
+@@ -599,6 +656,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 2.2.2.2 \
+@@ -610,6 +668,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 2.2.2.2 \
+@@ -621,6 +680,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 2.2.2.2 \
+@@ -632,6 +692,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 3.3.3.3 \
+@@ -643,6 +704,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 3.3.3.3 \
+@@ -654,6 +716,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 3.3.3.3 \
+@@ -665,6 +728,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -676,6 +740,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 1.1.1.1 \
+@@ -687,6 +752,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -698,6 +764,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -709,6 +776,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 2.2.2.2 \
+@@ -720,6 +788,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -731,6 +800,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -742,6 +812,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 3.3.3.3 \
+@@ -753,6 +824,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -764,6 +836,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -775,6 +848,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 1.1.1.1 \
+@@ -786,6 +860,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -797,6 +872,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -808,6 +884,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 2.2.2.2 \
+@@ -819,6 +896,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -830,6 +908,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -841,6 +920,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 3.3.3.3 \
+@@ -852,6 +932,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -863,6 +944,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -874,6 +956,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 1.1.1.1 \
+@@ -885,6 +968,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -896,6 +980,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -907,6 +992,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 2.2.2.2 \
+@@ -918,6 +1004,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -929,6 +1016,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -940,6 +1028,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 3.3.3.3 \
+@@ -951,6 +1040,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -962,6 +1052,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -973,6 +1064,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 1.1.1.1 \
+@@ -984,6 +1076,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -995,6 +1088,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -1006,6 +1100,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 2.2.2.2 \
+@@ -1017,6 +1112,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -1028,6 +1124,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -1039,6 +1136,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 3.3.3.3 \
+@@ -1050,6 +1148,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -1061,6 +1160,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -1072,6 +1172,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 1.1.1.1 \
+@@ -1083,6 +1184,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -1094,6 +1196,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -1105,6 +1208,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 2.2.2.2 \
+@@ -1116,6 +1220,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -1127,6 +1232,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -1138,6 +1244,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 3.3.3.3 \
+@@ -1149,6 +1256,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -1160,6 +1268,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -1171,6 +1280,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 1.1.1.1 \
+@@ -1182,6 +1292,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -1193,6 +1304,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -1204,6 +1316,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 2.2.2.2 \
+@@ -1215,6 +1328,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -1226,6 +1340,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -1237,6 +1352,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 3.3.3.3 \
+@@ -1248,6 +1364,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -1259,6 +1376,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -1270,6 +1388,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 1.1.1.1 \
+@@ -1281,6 +1400,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -1292,6 +1412,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -1303,6 +1424,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 2.2.2.2 \
+@@ -1314,6 +1436,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -1325,6 +1448,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -1336,6 +1460,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 3.3.3.3 \
+@@ -1347,6 +1472,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -1358,6 +1484,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -1369,6 +1496,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 1.1.1.1 \
+@@ -1380,6 +1508,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -1391,6 +1520,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -1402,6 +1532,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 2.2.2.2 \
+@@ -1413,6 +1544,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 2.2.2.2 \
+@@ -1424,6 +1556,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -1435,6 +1568,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 3.3.3.3 \
+@@ -1446,6 +1580,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 3.3.3.3 \
+@@ -1457,6 +1592,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 1.1.1.1 \
+@@ -1467,6 +1603,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 1.1.1.1 \
+@@ -1477,6 +1614,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 1.1.1.1 \
+@@ -1487,6 +1625,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 2.2.2.2 \
+@@ -1497,6 +1636,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 2.2.2.2 \
+@@ -1507,6 +1647,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 2.2.2.2 \
+@@ -1517,6 +1658,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 3.3.3.3 \
+@@ -1527,6 +1669,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 3.3.3.3 \
+@@ -1537,6 +1680,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 3.3.3.3 \
+@@ -1547,6 +1691,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 1.1.1.1 \
+@@ -1557,6 +1702,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 1.1.1.1 \
+@@ -1567,6 +1713,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 1.1.1.1 \
+@@ -1577,6 +1724,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 2.2.2.2 \
+@@ -1587,6 +1735,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 2.2.2.2 \
+@@ -1597,6 +1746,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 2.2.2.2 \
+@@ -1607,6 +1757,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 3.3.3.3 \
+@@ -1617,6 +1768,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 3.3.3.3 \
+@@ -1627,6 +1779,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 3.3.3.3 \
+@@ -1637,6 +1790,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 1.1.1.1 \
+@@ -1647,6 +1801,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 1.1.1.1 \
+@@ -1657,6 +1812,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 1.1.1.1 \
+@@ -1667,6 +1823,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 2.2.2.2 \
+@@ -1677,6 +1834,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 2.2.2.2 \
+@@ -1687,6 +1845,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 2.2.2.2 \
+@@ -1697,6 +1856,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 3.3.3.3 \
+@@ -1707,6 +1867,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 3.3.3.3 \
+@@ -1717,6 +1878,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 3.3.3.3 \
+@@ -1727,6 +1889,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 1.1.1.1 \
+@@ -1737,6 +1900,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 1.1.1.1 \
+@@ -1747,6 +1911,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 1.1.1.1 \
+@@ -1757,6 +1922,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 2.2.2.2 \
+@@ -1767,6 +1933,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 2.2.2.2 \
+@@ -1777,6 +1944,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 2.2.2.2 \
+@@ -1787,6 +1955,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 3.3.3.3 \
+@@ -1797,6 +1966,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 3.3.3.3 \
+@@ -1807,6 +1977,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 3.3.3.3 \
+diff --git a/tests/nwfilterxml2firewalldata/iter3-linux.args b/tests/nwfilterxml2firewalldata/iter3-linux.args
+index 0b16577992..cc6d442c75 100644
+--- a/tests/nwfilterxml2firewalldata/iter3-linux.args
++++ b/tests/nwfilterxml2firewalldata/iter3-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -9,6 +10,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 1.1.1.1 \
+@@ -19,6 +21,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -29,6 +32,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -39,6 +43,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --destination 1.1.1.1 \
+@@ -49,6 +54,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --source 1.1.1.1 \
+@@ -59,6 +65,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 2.2.2.2 \
+@@ -69,6 +76,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 2.2.2.2 \
+@@ -79,6 +87,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 2.2.2.2 \
+@@ -89,6 +98,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --source 2.2.2.2 \
+@@ -99,6 +109,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --destination 2.2.2.2 \
+@@ -109,6 +120,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --source 2.2.2.2 \
+@@ -119,6 +131,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --source 2.2.2.2 \
+@@ -130,6 +143,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --destination 2.2.2.2 \
+@@ -141,6 +155,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --source 2.2.2.2 \
+diff --git a/tests/nwfilterxml2firewalldata/mac-linux.args b/tests/nwfilterxml2firewalldata/mac-linux.args
+index 0fd9dbccc0..cc3aab2b92 100644
+--- a/tests/nwfilterxml2firewalldata/mac-linux.args
++++ b/tests/nwfilterxml2firewalldata/mac-linux.args
+@@ -1,22 +1,26 @@
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+ -p 0x806 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -d aa:bb:cc:dd:ee:ff/ff:ff:ff:ff:ff:ff \
+ -p 0x800 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -d aa:bb:cc:dd:ee:ff/ff:ff:ff:ff:ff:ff \
+ -p 0x600 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -d aa:bb:cc:dd:ee:ff/ff:ff:ff:ff:ff:ff \
+diff --git a/tests/nwfilterxml2firewalldata/rarp-linux.args b/tests/nwfilterxml2firewalldata/rarp-linux.args
+index f5fd6433bd..3e2441818c 100644
+--- a/tests/nwfilterxml2firewalldata/rarp-linux.args
++++ b/tests/nwfilterxml2firewalldata/rarp-linux.args
+@@ -1,7 +1,9 @@
+ ebtables \
++--concurrent \
+ -t nat \
+ -N libvirt-J-vnet0
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -14,6 +16,7 @@ ebtables \
+ --arp-mac-dst 0a:0b:0c:0d:0e:0f \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -23,6 +26,7 @@ ebtables \
+ --arp-ptype 0xff \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -32,6 +36,7 @@ ebtables \
+ --arp-ptype 0x100 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -41,6 +46,7 @@ ebtables \
+ --arp-ptype 0xffff \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A PREROUTING \
+ -i vnet0 \
+diff --git a/tests/nwfilterxml2firewalldata/sctp-ipv6-linux.args b/tests/nwfilterxml2firewalldata/sctp-ipv6-linux.args
+index 959c4e8e0f..fbe6f39198 100644
+--- a/tests/nwfilterxml2firewalldata/sctp-ipv6-linux.args
++++ b/tests/nwfilterxml2firewalldata/sctp-ipv6-linux.args
+@@ -1,4 +1,5 @@
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ -m mac \
+@@ -10,6 +11,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --source a:b:c::d:e:f/128 \
+@@ -19,6 +21,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ -m mac \
+@@ -30,6 +33,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --destination a:b:c::/128 \
+@@ -41,6 +45,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ -m mac \
+@@ -54,6 +59,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --destination a:b:c::/128 \
+@@ -65,6 +71,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --destination ::10.1.2.3/128 \
+@@ -76,6 +83,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ -m mac \
+@@ -89,6 +97,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --destination ::10.1.2.3/128 \
+diff --git a/tests/nwfilterxml2firewalldata/sctp-linux.args b/tests/nwfilterxml2firewalldata/sctp-linux.args
+index 671fc0480f..a3c5a7a72d 100644
+--- a/tests/nwfilterxml2firewalldata/sctp-linux.args
++++ b/tests/nwfilterxml2firewalldata/sctp-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ -m mac \
+@@ -10,6 +11,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ --source 10.1.2.3/32 \
+@@ -19,6 +21,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ -m mac \
+@@ -30,6 +33,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --destination 10.1.2.3/32 \
+@@ -41,6 +45,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ -m mac \
+@@ -54,6 +59,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --destination 10.1.2.3/32 \
+@@ -65,6 +71,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p sctp \
+ --destination 10.1.2.3/32 \
+@@ -76,6 +83,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p sctp \
+ -m mac \
+@@ -89,6 +97,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p sctp \
+ --destination 10.1.2.3/32 \
+diff --git a/tests/nwfilterxml2firewalldata/stp-linux.args b/tests/nwfilterxml2firewalldata/stp-linux.args
+index e3114ac622..76f5321856 100644
+--- a/tests/nwfilterxml2firewalldata/stp-linux.args
++++ b/tests/nwfilterxml2firewalldata/stp-linux.args
+@@ -1,32 +1,41 @@
+ ebtables \
++--concurrent \
+ -t nat \
+ -F J-vnet0-stp-xyz
+ ebtables \
++--concurrent \
+ -t nat \
+ -X J-vnet0-stp-xyz
+ ebtables \
++--concurrent \
+ -t nat \
+ -N J-vnet0-stp-xyz
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -d 01:80:c2:00:00:00 \
+ -j J-vnet0-stp-xyz
+ ebtables \
++--concurrent \
+ -t nat \
+ -F P-vnet0-stp-xyz
+ ebtables \
++--concurrent \
+ -t nat \
+ -X P-vnet0-stp-xyz
+ ebtables \
++--concurrent \
+ -t nat \
+ -N P-vnet0-stp-xyz
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -d 01:80:c2:00:00:00 \
+ -j P-vnet0-stp-xyz
+ ebtables \
++--concurrent \
+ -t nat \
+ -A P-vnet0-stp-xyz \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -35,6 +44,7 @@ ebtables \
+ --stp-flags 68 \
+ -j CONTINUE
+ ebtables \
++--concurrent \
+ -t nat \
+ -A J-vnet0-stp-xyz \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -44,6 +54,7 @@ ebtables \
+ --stp-root-cost 287454020:573785173 \
+ -j RETURN
+ ebtables \
++--concurrent \
+ -t nat \
+ -A P-vnet0-stp-xyz \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+diff --git a/tests/nwfilterxml2firewalldata/target-linux.args b/tests/nwfilterxml2firewalldata/target-linux.args
+index d219877716..5216c709dd 100644
+--- a/tests/nwfilterxml2firewalldata/target-linux.args
++++ b/tests/nwfilterxml2firewalldata/target-linux.args
+@@ -1,40 +1,47 @@
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+ -p 0x806 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+ -p 0x806 \
+ -j DROP
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+ -p 0x806 \
+ -j DROP
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -d aa:bb:cc:dd:ee:ff/ff:ff:ff:ff:ff:ff \
+ -p 0x800 \
+ -j ACCEPT
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -d aa:bb:cc:dd:ee:ff/ff:ff:ff:ff:ff:ff \
+ -p 0x800 \
+ -j DROP
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -d aa:bb:cc:dd:ee:ff/ff:ff:ff:ff:ff:ff \
+ -p 0x800 \
+ -j DROP
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m mac \
+@@ -49,6 +56,7 @@ iptables \
+ -- dir out' \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ --source 10.1.2.3/32 \
+@@ -61,6 +69,7 @@ iptables \
+ -- dir out' \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m mac \
+@@ -75,6 +84,7 @@ iptables \
+ -- dir out' \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m mac \
+@@ -87,6 +97,7 @@ iptables \
+ -- dir out' \
+ -j DROP
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ --source 10.1.2.3/32 \
+@@ -97,6 +108,7 @@ iptables \
+ -- dir out' \
+ -j DROP
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m mac \
+@@ -109,6 +121,7 @@ iptables \
+ -- dir out' \
+ -j DROP
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m mac \
+@@ -121,6 +134,7 @@ iptables \
+ -- dir out' \
+ -j REJECT
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ --source 10.1.2.3/32 \
+@@ -131,6 +145,7 @@ iptables \
+ -- dir out' \
+ -j REJECT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m mac \
+@@ -143,6 +158,7 @@ iptables \
+ -- dir out' \
+ -j REJECT
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ --destination 10.1.2.3/22 \
+@@ -155,6 +171,7 @@ iptables \
+ -- dir in' \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m mac \
+@@ -169,6 +186,7 @@ iptables \
+ -- dir in' \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ --destination 10.1.2.3/22 \
+@@ -181,6 +199,7 @@ iptables \
+ -- dir in' \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ --destination 10.1.2.3/22 \
+@@ -191,6 +210,7 @@ iptables \
+ -- dir in' \
+ -j DROP
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m mac \
+@@ -203,6 +223,7 @@ iptables \
+ -- dir in' \
+ -j DROP
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ --destination 10.1.2.3/22 \
+@@ -213,6 +234,7 @@ iptables \
+ -- dir in' \
+ -j DROP
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ --destination 10.1.2.3/22 \
+@@ -223,6 +245,7 @@ iptables \
+ -- dir in' \
+ -j REJECT
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m mac \
+@@ -235,6 +258,7 @@ iptables \
+ -- dir in' \
+ -j REJECT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ --destination 10.1.2.3/22 \
+@@ -245,6 +269,7 @@ iptables \
+ -- dir in' \
+ -j REJECT
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m comment \
+@@ -252,6 +277,7 @@ iptables \
+ -- dir inout' \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m comment \
+@@ -259,6 +285,7 @@ iptables \
+ -- dir inout' \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m comment \
+@@ -266,6 +293,7 @@ iptables \
+ -- dir inout' \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m comment \
+@@ -273,6 +301,7 @@ iptables \
+ -- dir inout' \
+ -j DROP
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m comment \
+@@ -280,6 +309,7 @@ iptables \
+ -- dir inout' \
+ -j DROP
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m comment \
+@@ -287,6 +317,7 @@ iptables \
+ -- dir inout' \
+ -j DROP
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -m comment \
+@@ -294,6 +325,7 @@ iptables \
+ -- dir inout' \
+ -j REJECT
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -m comment \
+@@ -301,6 +333,7 @@ iptables \
+ -- dir inout' \
+ -j REJECT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -m comment \
+diff --git a/tests/nwfilterxml2firewalldata/target2-linux.args b/tests/nwfilterxml2firewalldata/target2-linux.args
+index cfa4f589d6..c774f6f24a 100644
+--- a/tests/nwfilterxml2firewalldata/target2-linux.args
++++ b/tests/nwfilterxml2firewalldata/target2-linux.args
+@@ -1,19 +1,23 @@
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --dport 22 \
+ -j ACCEPT
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --sport 22 \
+ -j RETURN
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --sport 22 \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --sport 80 \
+@@ -21,6 +25,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --dport 80 \
+@@ -28,6 +33,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --sport 80 \
+@@ -35,26 +41,32 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ -j REJECT
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ -j REJECT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ -j REJECT
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p all \
+ -j DROP
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p all \
+ -j DROP
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p all \
+ -j DROP
+diff --git a/tests/nwfilterxml2firewalldata/tcp-ipv6-linux.args b/tests/nwfilterxml2firewalldata/tcp-ipv6-linux.args
+index e6f8de3fca..8fa5e24eff 100644
+--- a/tests/nwfilterxml2firewalldata/tcp-ipv6-linux.args
++++ b/tests/nwfilterxml2firewalldata/tcp-ipv6-linux.args
+@@ -1,4 +1,5 @@
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ -m mac \
+@@ -10,6 +11,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --source a:b:c::d:e:f/128 \
+@@ -19,6 +21,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ -m mac \
+@@ -30,6 +33,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --destination a:b:c::/128 \
+@@ -41,6 +45,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ -m mac \
+@@ -54,6 +59,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --destination a:b:c::/128 \
+@@ -65,6 +71,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --destination ::10.1.2.3/128 \
+@@ -76,6 +83,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ -m mac \
+@@ -89,6 +97,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --destination ::10.1.2.3/128 \
+diff --git a/tests/nwfilterxml2firewalldata/tcp-linux.args b/tests/nwfilterxml2firewalldata/tcp-linux.args
+index 195bfc01e6..74ac4a6733 100644
+--- a/tests/nwfilterxml2firewalldata/tcp-linux.args
++++ b/tests/nwfilterxml2firewalldata/tcp-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ -m mac \
+@@ -10,6 +11,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --source 10.1.2.3/32 \
+@@ -19,6 +21,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ -m mac \
+@@ -30,6 +33,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --destination 10.1.2.3/32 \
+@@ -39,6 +43,7 @@ iptables \
+ --sport 100:1111 \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ -m mac \
+@@ -50,6 +55,7 @@ iptables \
+ --dport 100:1111 \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --destination 10.1.2.3/32 \
+@@ -59,6 +65,7 @@ iptables \
+ --sport 100:1111 \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p tcp \
+ --destination 10.1.2.3/32 \
+@@ -68,6 +75,7 @@ iptables \
+ --sport 65535:65535 \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ -m mac \
+@@ -79,6 +87,7 @@ iptables \
+ --dport 65535:65535 \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p tcp \
+ --destination 10.1.2.3/32 \
+@@ -88,21 +97,25 @@ iptables \
+ --sport 65535:65535 \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --tcp-flags SYN ALL \
+ -j ACCEPT
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --tcp-flags SYN SYN,ACK \
+ -j ACCEPT
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --tcp-flags RST NONE \
+ -j ACCEPT
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p tcp \
+ --tcp-flags PSH NONE \
+diff --git a/tests/nwfilterxml2firewalldata/udp-ipv6-linux.args b/tests/nwfilterxml2firewalldata/udp-ipv6-linux.args
+index 9183c08753..59367ed3d3 100644
+--- a/tests/nwfilterxml2firewalldata/udp-ipv6-linux.args
++++ b/tests/nwfilterxml2firewalldata/udp-ipv6-linux.args
+@@ -1,4 +1,5 @@
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ -m mac \
+@@ -10,6 +11,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --source a:b:c::d:e:f/128 \
+@@ -19,6 +21,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ -m mac \
+@@ -30,6 +33,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --destination ::a:b:c/128 \
+@@ -41,6 +45,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ -m mac \
+@@ -54,6 +59,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --destination ::a:b:c/128 \
+@@ -65,6 +71,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --destination ::10.1.2.3/128 \
+@@ -76,6 +83,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ -m mac \
+@@ -89,6 +97,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --destination ::10.1.2.3/128 \
+diff --git a/tests/nwfilterxml2firewalldata/udp-linux.args b/tests/nwfilterxml2firewalldata/udp-linux.args
+index 910d648a8a..32a8f56dfc 100644
+--- a/tests/nwfilterxml2firewalldata/udp-linux.args
++++ b/tests/nwfilterxml2firewalldata/udp-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ -m mac \
+@@ -10,6 +11,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ --source 10.1.2.3/32 \
+@@ -19,6 +21,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ -m mac \
+@@ -30,6 +33,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --destination 10.1.2.3/32 \
+@@ -41,6 +45,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ -m mac \
+@@ -54,6 +59,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --destination 10.1.2.3/32 \
+@@ -65,6 +71,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udp \
+ --destination 10.1.2.3/32 \
+@@ -76,6 +83,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udp \
+ -m mac \
+@@ -89,6 +97,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udp \
+ --destination 10.1.2.3/32 \
+diff --git a/tests/nwfilterxml2firewalldata/udplite-ipv6-linux.args b/tests/nwfilterxml2firewalldata/udplite-ipv6-linux.args
+index 9eb38d7e6d..de564aee36 100644
+--- a/tests/nwfilterxml2firewalldata/udplite-ipv6-linux.args
++++ b/tests/nwfilterxml2firewalldata/udplite-ipv6-linux.args
+@@ -1,4 +1,5 @@
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p udplite \
+ -m mac \
+@@ -11,6 +12,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p udplite \
+ --destination f:e:d::c:b:a/127 \
+@@ -21,6 +23,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p udplite \
+ -m mac \
+@@ -33,6 +36,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p udplite \
+ --destination a:b:c::/128 \
+@@ -42,6 +46,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p udplite \
+ -m mac \
+@@ -53,6 +58,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p udplite \
+ --destination a:b:c::/128 \
+@@ -62,6 +68,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FJ-vnet0 \
+ -p udplite \
+ --destination ::10.1.2.3/128 \
+@@ -71,6 +78,7 @@ ip6tables \
+ --state ESTABLISHED \
+ -j RETURN
+ ip6tables \
++-w \
+ -A FP-vnet0 \
+ -p udplite \
+ -m mac \
+@@ -82,6 +90,7 @@ ip6tables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ ip6tables \
++-w \
+ -A HJ-vnet0 \
+ -p udplite \
+ --destination ::10.1.2.3/128 \
+diff --git a/tests/nwfilterxml2firewalldata/udplite-linux.args b/tests/nwfilterxml2firewalldata/udplite-linux.args
+index 53bc667459..8f3a9e8f24 100644
+--- a/tests/nwfilterxml2firewalldata/udplite-linux.args
++++ b/tests/nwfilterxml2firewalldata/udplite-linux.args
+@@ -1,4 +1,5 @@
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udplite \
+ -m mac \
+@@ -10,6 +11,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udplite \
+ --source 10.1.2.3/32 \
+@@ -19,6 +21,7 @@ iptables \
+ --state ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udplite \
+ -m mac \
+@@ -30,6 +33,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udplite \
+ --destination 10.1.2.3/22 \
+@@ -39,6 +43,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udplite \
+ -m mac \
+@@ -50,6 +55,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udplite \
+ --destination 10.1.2.3/22 \
+@@ -59,6 +65,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FJ-vnet0 \
+ -p udplite \
+ --destination 10.1.2.3/22 \
+@@ -68,6 +75,7 @@ iptables \
+ --state ESTABLISHED \
+ -j RETURN
+ iptables \
++-w \
+ -A FP-vnet0 \
+ -p udplite \
+ -m mac \
+@@ -79,6 +87,7 @@ iptables \
+ --state NEW,ESTABLISHED \
+ -j ACCEPT
+ iptables \
++-w \
+ -A HJ-vnet0 \
+ -p udplite \
+ --destination 10.1.2.3/22 \
+diff --git a/tests/nwfilterxml2firewalldata/vlan-linux.args b/tests/nwfilterxml2firewalldata/vlan-linux.args
+index 0a8204c4dc..a93c09cfbd 100644
+--- a/tests/nwfilterxml2firewalldata/vlan-linux.args
++++ b/tests/nwfilterxml2firewalldata/vlan-linux.args
+@@ -1,4 +1,5 @@
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -d 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -7,6 +8,7 @@ ebtables \
+ --vlan-id 291 \
+ -j CONTINUE
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -15,6 +17,7 @@ ebtables \
+ --vlan-id 291 \
+ -j CONTINUE
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -d 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -23,6 +26,7 @@ ebtables \
+ --vlan-id 1234 \
+ -j RETURN
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -31,6 +35,7 @@ ebtables \
+ --vlan-id 1234 \
+ -j RETURN
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-P-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -39,6 +44,7 @@ ebtables \
+ --vlan-id 291 \
+ -j DROP
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+@@ -47,6 +53,7 @@ ebtables \
+ --vlan-encap 2054 \
+ -j DROP
+ ebtables \
++--concurrent \
+ -t nat \
+ -A libvirt-J-vnet0 \
+ -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \
+diff --git a/tests/nwfilterxml2firewalltest.c b/tests/nwfilterxml2firewalltest.c
+index da86ec9463..c97f83b24a 100644
+--- a/tests/nwfilterxml2firewalltest.c
++++ b/tests/nwfilterxml2firewalltest.c
+@@ -58,90 +58,90 @@ struct _virNWFilterInst {
+ 
+ static const char *commonRules[] = {
+     /* Dropping ebtables rules */
+-    "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-J-vnet0\n"
+-    "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-P-vnet0\n"
+-    "ebtables -t nat -L libvirt-J-vnet0\n"
+-    "ebtables -t nat -L libvirt-P-vnet0\n"
+-    "ebtables -t nat -F libvirt-J-vnet0\n"
+-    "ebtables -t nat -X libvirt-J-vnet0\n"
+-    "ebtables -t nat -F libvirt-P-vnet0\n"
+-    "ebtables -t nat -X libvirt-P-vnet0\n",
++    "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-J-vnet0\n"
++    "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-P-vnet0\n"
++    "ebtables --concurrent -t nat -L libvirt-J-vnet0\n"
++    "ebtables --concurrent -t nat -L libvirt-P-vnet0\n"
++    "ebtables --concurrent -t nat -F libvirt-J-vnet0\n"
++    "ebtables --concurrent -t nat -X libvirt-J-vnet0\n"
++    "ebtables --concurrent -t nat -F libvirt-P-vnet0\n"
++    "ebtables --concurrent -t nat -X libvirt-P-vnet0\n",
+ 
+     /* Creating ebtables chains */
+-    "ebtables -t nat -N libvirt-J-vnet0\n"
+-    "ebtables -t nat -N libvirt-P-vnet0\n",
++    "ebtables --concurrent -t nat -N libvirt-J-vnet0\n"
++    "ebtables --concurrent -t nat -N libvirt-P-vnet0\n",
+ 
+     /* Dropping iptables rules */
+-    "iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n"
+-    "iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n"
+-    "iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n"
+-    "iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n"
+-    "iptables -F FP-vnet0\n"
+-    "iptables -X FP-vnet0\n"
+-    "iptables -F FJ-vnet0\n"
+-    "iptables -X FJ-vnet0\n"
+-    "iptables -F HJ-vnet0\n"
+-    "iptables -X HJ-vnet0\n",
++    "iptables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n"
++    "iptables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n"
++    "iptables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n"
++    "iptables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n"
++    "iptables -w -F FP-vnet0\n"
++    "iptables -w -X FP-vnet0\n"
++    "iptables -w -F FJ-vnet0\n"
++    "iptables -w -X FJ-vnet0\n"
++    "iptables -w -F HJ-vnet0\n"
++    "iptables -w -X HJ-vnet0\n",
+ 
+     /* Creating iptables chains */
+-    "iptables -N libvirt-in\n"
+-    "iptables -N libvirt-out\n"
+-    "iptables -N libvirt-in-post\n"
+-    "iptables -N libvirt-host-in\n"
+-    "iptables -D FORWARD -j libvirt-in\n"
+-    "iptables -D FORWARD -j libvirt-out\n"
+-    "iptables -D FORWARD -j libvirt-in-post\n"
+-    "iptables -D INPUT -j libvirt-host-in\n"
+-    "iptables -I FORWARD 1 -j libvirt-in\n"
+-    "iptables -I FORWARD 2 -j libvirt-out\n"
+-    "iptables -I FORWARD 3 -j libvirt-in-post\n"
+-    "iptables -I INPUT 1 -j libvirt-host-in\n"
+-    "iptables -N FP-vnet0\n"
+-    "iptables -N FJ-vnet0\n"
+-    "iptables -N HJ-vnet0\n"
+-    "iptables -A libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n"
+-    "iptables -A libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n"
+-    "iptables -A libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n"
+-    "iptables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
+-    "iptables -A libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n",
++    "iptables -w -N libvirt-in\n"
++    "iptables -w -N libvirt-out\n"
++    "iptables -w -N libvirt-in-post\n"
++    "iptables -w -N libvirt-host-in\n"
++    "iptables -w -D FORWARD -j libvirt-in\n"
++    "iptables -w -D FORWARD -j libvirt-out\n"
++    "iptables -w -D FORWARD -j libvirt-in-post\n"
++    "iptables -w -D INPUT -j libvirt-host-in\n"
++    "iptables -w -I FORWARD 1 -j libvirt-in\n"
++    "iptables -w -I FORWARD 2 -j libvirt-out\n"
++    "iptables -w -I FORWARD 3 -j libvirt-in-post\n"
++    "iptables -w -I INPUT 1 -j libvirt-host-in\n"
++    "iptables -w -N FP-vnet0\n"
++    "iptables -w -N FJ-vnet0\n"
++    "iptables -w -N HJ-vnet0\n"
++    "iptables -w -A libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n"
++    "iptables -w -A libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n"
++    "iptables -w -A libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n"
++    "iptables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
++    "iptables -w -A libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n",
+ 
+     /* Dropping ip6tables rules */
+-    "ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n"
+-    "ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n"
+-    "ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n"
+-    "ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n"
+-    "ip6tables -F FP-vnet0\n"
+-    "ip6tables -X FP-vnet0\n"
+-    "ip6tables -F FJ-vnet0\n"
+-    "ip6tables -X FJ-vnet0\n"
+-    "ip6tables -F HJ-vnet0\n"
+-    "ip6tables -X HJ-vnet0\n",
++    "ip6tables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n"
++    "ip6tables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n"
++    "ip6tables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n"
++    "ip6tables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n"
++    "ip6tables -w -F FP-vnet0\n"
++    "ip6tables -w -X FP-vnet0\n"
++    "ip6tables -w -F FJ-vnet0\n"
++    "ip6tables -w -X FJ-vnet0\n"
++    "ip6tables -w -F HJ-vnet0\n"
++    "ip6tables -w -X HJ-vnet0\n",
+ 
+     /* Creating ip6tables chains */
+-    "ip6tables -N libvirt-in\n"
+-    "ip6tables -N libvirt-out\n"
+-    "ip6tables -N libvirt-in-post\n"
+-    "ip6tables -N libvirt-host-in\n"
+-    "ip6tables -D FORWARD -j libvirt-in\n"
+-    "ip6tables -D FORWARD -j libvirt-out\n"
+-    "ip6tables -D FORWARD -j libvirt-in-post\n"
+-    "ip6tables -D INPUT -j libvirt-host-in\n"
+-    "ip6tables -I FORWARD 1 -j libvirt-in\n"
+-    "ip6tables -I FORWARD 2 -j libvirt-out\n"
+-    "ip6tables -I FORWARD 3 -j libvirt-in-post\n"
+-    "ip6tables -I INPUT 1 -j libvirt-host-in\n"
+-    "ip6tables -N FP-vnet0\n"
+-    "ip6tables -N FJ-vnet0\n"
+-    "ip6tables -N HJ-vnet0\n"
+-    "ip6tables -A libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n"
+-    "ip6tables -A libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n"
+-    "ip6tables -A libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n"
+-    "ip6tables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
+-    "ip6tables -A libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n",
++    "ip6tables -w -N libvirt-in\n"
++    "ip6tables -w -N libvirt-out\n"
++    "ip6tables -w -N libvirt-in-post\n"
++    "ip6tables -w -N libvirt-host-in\n"
++    "ip6tables -w -D FORWARD -j libvirt-in\n"
++    "ip6tables -w -D FORWARD -j libvirt-out\n"
++    "ip6tables -w -D FORWARD -j libvirt-in-post\n"
++    "ip6tables -w -D INPUT -j libvirt-host-in\n"
++    "ip6tables -w -I FORWARD 1 -j libvirt-in\n"
++    "ip6tables -w -I FORWARD 2 -j libvirt-out\n"
++    "ip6tables -w -I FORWARD 3 -j libvirt-in-post\n"
++    "ip6tables -w -I INPUT 1 -j libvirt-host-in\n"
++    "ip6tables -w -N FP-vnet0\n"
++    "ip6tables -w -N FJ-vnet0\n"
++    "ip6tables -w -N HJ-vnet0\n"
++    "ip6tables -w -A libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n"
++    "ip6tables -w -A libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n"
++    "ip6tables -w -A libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n"
++    "ip6tables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n"
++    "ip6tables -w -A libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n",
+ 
+     /* Inserting ebtables rules */
+-    "ebtables -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n"
+-    "ebtables -t nat -A POSTROUTING -o vnet0 -j libvirt-P-vnet0\n",
++    "ebtables --concurrent -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n"
++    "ebtables --concurrent -t nat -A POSTROUTING -o vnet0 -j libvirt-P-vnet0\n",
+ };
+ 
+ 
+diff --git a/tests/virfirewalltest.c b/tests/virfirewalltest.c
+index 8aba127610..195163a985 100644
+--- a/tests/virfirewalltest.c
++++ b/tests/virfirewalltest.c
+@@ -147,17 +147,19 @@ VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block,
+                                  "org.firewalld.error",
+                                  "something bad happened");
+         } else {
+-            if (nargs == 1 &&
++            if (nargs == 2 &&
+                 STREQ(type, "ipv4") &&
+-                STREQ(args[0], "-L")) {
++                STREQ(args[0], "-w") &&
++                STREQ(args[1], "-L")) {
+                 if (virDBusCreateReply(&reply,
+                                        "s", TEST_FILTER_TABLE_LIST) < 0)
+                     goto error;
+-            } else if (nargs == 3 &&
++            } else if (nargs == 4 &&
+                        STREQ(type, "ipv4") &&
+-                       STREQ(args[0], "-t") &&
+-                       STREQ(args[1], "nat") &&
+-                       STREQ(args[2], "-L")) {
++                       STREQ(args[0], "-w") &&
++                       STREQ(args[1], "-t") &&
++                       STREQ(args[2], "nat") &&
++                       STREQ(args[3], "-L")) {
+                 if (virDBusCreateReply(&reply,
+                                        "s", TEST_NAT_TABLE_LIST) < 0)
+                     goto error;
+@@ -204,8 +206,8 @@ testFirewallSingleGroup(const void *opaque)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -A INPUT --source-host '!192.168.122.1' --jump REJECT\n";
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n";
+     const struct testFirewallData *data = opaque;
+ 
+     fwDisabled = data->fwDisabled;
+@@ -260,8 +262,8 @@ testFirewallRemoveRule(const void *opaque)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -A INPUT --source-host '!192.168.122.1' --jump REJECT\n";
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n";
+     const struct testFirewallData *data = opaque;
+     virFirewallRulePtr fwrule;
+ 
+@@ -323,10 +325,10 @@ testFirewallManyGroups(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"
+-        IPTABLES_PATH " -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -A OUTPUT --jump DROP\n";
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"
++        IPTABLES_PATH " -w -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A OUTPUT --jump DROP\n";
+     const struct testFirewallData *data = opaque;
+ 
+     fwDisabled = data->fwDisabled;
+@@ -414,10 +416,10 @@ testFirewallIgnoreFailGroup(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -A OUTPUT --jump DROP\n";
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A OUTPUT --jump DROP\n";
+     const struct testFirewallData *data = opaque;
+ 
+     fwDisabled = data->fwDisabled;
+@@ -486,10 +488,10 @@ testFirewallIgnoreFailRule(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -A OUTPUT --jump DROP\n";
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A OUTPUT --jump DROP\n";
+     const struct testFirewallData *data = opaque;
+ 
+     fwDisabled = data->fwDisabled;
+@@ -557,8 +559,8 @@ testFirewallNoRollback(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.255 --jump REJECT\n";
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n";
+     const struct testFirewallData *data = opaque;
+ 
+     fwDisabled = data->fwDisabled;
+@@ -621,11 +623,11 @@ testFirewallSingleRollback(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -D INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -D INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -D INPUT --source-host '!192.168.122.1' --jump REJECT\n";
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n";
+     const struct testFirewallData *data = opaque;
+ 
+     fwDisabled = data->fwDisabled;
+@@ -705,10 +707,10 @@ testFirewallManyRollback(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -D INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -D INPUT --source-host '!192.168.122.1' --jump REJECT\n";
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n";
+     const struct testFirewallData *data = opaque;
+ 
+     fwDisabled = data->fwDisabled;
+@@ -792,14 +794,14 @@ testFirewallChainedRollback(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.127 --jump REJECT\n"
+-        IPTABLES_PATH " -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -D INPUT --source-host 192.168.122.127 --jump REJECT\n"
+-        IPTABLES_PATH " -D INPUT --source-host '!192.168.122.1' --jump REJECT\n"
+-        IPTABLES_PATH " -D INPUT --source-host 192.168.122.255 --jump REJECT\n"
+-        IPTABLES_PATH " -D INPUT --source-host '!192.168.122.1' --jump REJECT\n";
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.127 --jump REJECT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.127 --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.255 --jump REJECT\n"
++        IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n";
+     const struct testFirewallData *data = opaque;
+ 
+     fwDisabled = data->fwDisabled;
+@@ -938,12 +940,14 @@ testFirewallQueryHook(const char *const*args,
+                       void *opaque G_GNUC_UNUSED)
+ {
+     if (STREQ(args[0], IPTABLES_PATH) &&
+-        STREQ(args[1], "-L")) {
++        STREQ(args[1], "-w") &&
++        STREQ(args[2], "-L")) {
+         *output = g_strdup(TEST_FILTER_TABLE_LIST);
+     } else if (STREQ(args[0], IPTABLES_PATH) &&
+-               STREQ(args[1], "-t") &&
+-               STREQ(args[2], "nat") &&
+-               STREQ(args[3], "-L")) {
++               STREQ(args[1], "-w") &&
++               STREQ(args[2], "-t") &&
++               STREQ(args[3], "nat") &&
++               STREQ(args[4], "-L")) {
+         *output = g_strdup(TEST_NAT_TABLE_LIST);
+     }
+ }
+@@ -986,15 +990,15 @@ testFirewallQuery(const void *opaque G_GNUC_UNUSED)
+     int ret = -1;
+     const char *actual = NULL;
+     const char *expected =
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.127 --jump REJECT\n"
+-        IPTABLES_PATH " -L\n"
+-        IPTABLES_PATH " -t nat -L\n"
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.130 --jump REJECT\n"
+-        IPTABLES_PATH " -A INPUT --source-host '!192.168.122.129' --jump REJECT\n"
+-        IPTABLES_PATH " -A INPUT --source-host '!192.168.122.129' --jump REJECT\n"
+-        IPTABLES_PATH " -A INPUT --source-host 192.168.122.128 --jump REJECT\n"
+-        IPTABLES_PATH " -A INPUT --source-host '!192.168.122.1' --jump REJECT\n";
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.127 --jump REJECT\n"
++        IPTABLES_PATH " -w -L\n"
++        IPTABLES_PATH " -w -t nat -L\n"
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.130 --jump REJECT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.129' --jump REJECT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.129' --jump REJECT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.128 --jump REJECT\n"
++        IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n";
+     const struct testFirewallData *data = opaque;
+ 
+     expectedLineNum = 0;
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-util-virNetDevTapCreate-initialize-fd-to-1.patch b/SOURCES/libvirt-util-virNetDevTapCreate-initialize-fd-to-1.patch
new file mode 100644
index 0000000..d2a583f
--- /dev/null
+++ b/SOURCES/libvirt-util-virNetDevTapCreate-initialize-fd-to-1.patch
@@ -0,0 +1,37 @@
+From 3b2892c175918021f78a7dfc8dac39f4c451a15f Mon Sep 17 00:00:00 2001
+Message-Id: <3b2892c175918021f78a7dfc8dac39f4c451a15f@dist-git>
+From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
+Date: Sat, 12 Dec 2020 22:04:53 -0500
+Subject: [PATCH] util: virNetDevTapCreate: initialize fd to -1
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Fixes: 95089f481e003d971fe0a082018216c58c1b80e5
+(cherry picked from commit 2b6cd855042984b87beb7e3c30b67b0f586d89bb)
+
+https://bugzilla.redhat.com/1874304
+Signed-off-by: Laine Stump <laine@redhat.com>
+Message-Id: <20201213030453.48851-4-laine@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+---
+ src/util/virnetdevtap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c
+index fd4b70df30..d333163ff9 100644
+--- a/src/util/virnetdevtap.c
++++ b/src/util/virnetdevtap.c
+@@ -318,7 +318,7 @@ int virNetDevTapCreate(char **ifname,
+     size_t i = 0;
+     struct ifreq ifr;
+     int ret = -1;
+-    int fd = 0;
++    int fd = -1;
+ 
+     virMutexLock(&virNetDevTapCreateMutex);
+ 
+-- 
+2.29.2
+
diff --git a/SOURCES/libvirt-util-virhostcpu-Fail-when-fetching-CPU-Stats-for-invalid-cpu.patch b/SOURCES/libvirt-util-virhostcpu-Fail-when-fetching-CPU-Stats-for-invalid-cpu.patch
new file mode 100644
index 0000000..34c2060
--- /dev/null
+++ b/SOURCES/libvirt-util-virhostcpu-Fail-when-fetching-CPU-Stats-for-invalid-cpu.patch
@@ -0,0 +1,102 @@
+From ff54ea3d2a61a25079339d38caa6c509cf697ce3 Mon Sep 17 00:00:00 2001
+Message-Id: <ff54ea3d2a61a25079339d38caa6c509cf697ce3@dist-git>
+From: "Mauro S. M. Rodrigues" <maurosr@linux.vnet.ibm.com>
+Date: Tue, 19 Jan 2021 21:04:08 -0300
+Subject: [PATCH] util: virhostcpu: Fail when fetching CPU Stats for invalid
+ cpu
+
+virHostCPUGetStatsLinux walks through every cpu in /proc/stat until it
+finds cpu%cpuNum that matches with the requested cpu.
+If none is found it logs the error but it should return -1, instead of 0.
+Otherwise virsh nodecpustats --cpu <invalid cpu number> and API bindings
+don't fail properly, printing a blank line instead of an error message.
+
+This patch also includes an additional test for virhostcputest to avoid
+this regression to happen again in the future.
+
+Fixes: 93af79fba3fd75a8df6b7ca608719dd97f9511a0
+Reported-by: Satheesh Rajendran <satheera@in.ibm.com>
+Signed-off-by: Mauro S. M. Rodrigues <maurosr@linux.vnet.ibm.com>
+Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+Reviewed-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Tested-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+(cherry picked from commit 75a4ec42f70b5324f95d7ffbbfbf7457620735e4)
+
+https://bugzilla.redhat.com/1915183
+
+Signed-off-by: Daniel Henrique Barboza <dbarboza@redhat.com>
+Message-Id: <20210120000408.106596-1-dbarboza@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virhostcpu.c  |  2 +-
+ tests/virhostcputest.c | 21 ++++++++++++++++++---
+ 2 files changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
+index 218272d7ec..37cc45e3a6 100644
+--- a/src/util/virhostcpu.c
++++ b/src/util/virhostcpu.c
+@@ -855,7 +855,7 @@ virHostCPUGetStatsLinux(FILE *procstat,
+                         _("Invalid cpuNum in %s"),
+                         __FUNCTION__);
+ 
+-    return 0;
++    return -1;
+ }
+ 
+ 
+diff --git a/tests/virhostcputest.c b/tests/virhostcputest.c
+index 7865b61578..70a723098b 100644
+--- a/tests/virhostcputest.c
++++ b/tests/virhostcputest.c
+@@ -196,6 +196,7 @@ linuxTestHostCPU(const void *opaque)
+ struct nodeCPUStatsData {
+     const char *name;
+     int ncpus;
++    bool shouldFail;
+ };
+ 
+ static int
+@@ -214,6 +215,19 @@ linuxTestNodeCPUStats(const void *data)
+     result = linuxCPUStatsCompareFiles(cpustatfile,
+                                        testData->ncpus,
+                                        outfile);
++    if (result < 0) {
++        if (testData->shouldFail) {
++            /* Expected error */
++            result = 0;
++        }
++    } else {
++        if (testData->shouldFail) {
++            fprintf(stderr, "Expected a failure, got success");
++            result = -1;
++        }
++    }
++
++
+     VIR_FREE(cpustatfile);
+     VIR_FREE(outfile);
+     return result;
+@@ -258,14 +272,15 @@ mymain(void)
+         if (virTestRun(nodeData[i].testName, linuxTestHostCPU, &nodeData[i]) != 0)
+             ret = -1;
+ 
+-# define DO_TEST_CPU_STATS(name, ncpus) \
++# define DO_TEST_CPU_STATS(name, ncpus, shouldFail) \
+     do { \
+-        static struct nodeCPUStatsData data = { name, ncpus }; \
++        static struct nodeCPUStatsData data = { name, ncpus, shouldFail}; \
+         if (virTestRun("CPU stats " name, linuxTestNodeCPUStats, &data) < 0) \
+             ret = -1; \
+     } while (0)
+ 
+-    DO_TEST_CPU_STATS("24cpu", 24);
++    DO_TEST_CPU_STATS("24cpu", 24, false);
++    DO_TEST_CPU_STATS("24cpu", 25, true);
+ 
+     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-virDomainNetFindIdx-add-support-for-CCW-addresses.patch b/SOURCES/libvirt-virDomainNetFindIdx-add-support-for-CCW-addresses.patch
new file mode 100644
index 0000000..44beadb
--- /dev/null
+++ b/SOURCES/libvirt-virDomainNetFindIdx-add-support-for-CCW-addresses.patch
@@ -0,0 +1,138 @@
+From 606da680fb4c7ee0f8a7ecc76057592433ea6ac9 Mon Sep 17 00:00:00 2001
+Message-Id: <606da680fb4c7ee0f8a7ecc76057592433ea6ac9@dist-git>
+From: Cornelia Huck <cohuck@redhat.com>
+Date: Fri, 2 Oct 2020 13:39:12 +0200
+Subject: [PATCH] virDomainNetFindIdx: add support for CCW addresses
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Allow to match with CCW addresses in addition to PCI addresses
+(and MAC addresses).
+
+Signed-off-by: Cornelia Huck <cohuck@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+(cherry picked from commit 2fefbd03ab09f32b1b15d093096fa44870817751)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1837495
+
+Signed-off-by: Ján Tomko <jtomko@redhat.com>
+Message-Id: <a53fc421152b209c5a7fe69d4d5714a2f35077a8.1601638699.git.jtomko@redhat.com>
+Acked-by: Cornelia Huck <cohuck@redhat.com>
+---
+ src/conf/device_conf.c   | 12 ++++++++++++
+ src/conf/device_conf.h   |  3 +++
+ src/conf/domain_conf.c   | 23 ++++++++++++++++++++++-
+ src/libvirt_private.syms |  1 +
+ 4 files changed, 38 insertions(+), 1 deletion(-)
+
+diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c
+index 4dbd5c1ac9..9e96d08394 100644
+--- a/src/conf/device_conf.c
++++ b/src/conf/device_conf.c
+@@ -370,6 +370,18 @@ virDomainDeviceCCWAddressParseXML(xmlNodePtr node,
+     return ret;
+ }
+ 
++bool
++virDomainDeviceCCWAddressEqual(virDomainDeviceCCWAddressPtr addr1,
++                               virDomainDeviceCCWAddressPtr addr2)
++{
++    if (addr1->cssid == addr2->cssid &&
++        addr1->ssid == addr2->ssid &&
++        addr1->devno == addr2->devno) {
++        return true;
++    }
++    return false;
++}
++
+ int
+ virDomainDeviceDriveAddressParseXML(xmlNodePtr node,
+                                     virDomainDeviceDriveAddressPtr addr)
+diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h
+index e091d7cfe2..7a8227e743 100644
+--- a/src/conf/device_conf.h
++++ b/src/conf/device_conf.h
+@@ -208,6 +208,9 @@ void virPCIDeviceAddressFormat(virBufferPtr buf,
+ bool virDomainDeviceCCWAddressIsValid(virDomainDeviceCCWAddressPtr addr);
+ int virDomainDeviceCCWAddressParseXML(xmlNodePtr node,
+                                       virDomainDeviceCCWAddressPtr addr);
++bool virDomainDeviceCCWAddressEqual(virDomainDeviceCCWAddressPtr addr1,
++                                    virDomainDeviceCCWAddressPtr addr2);
++#define VIR_CCW_DEVICE_ADDRESS_FMT "%x.%x.%04x"
+ 
+ int virDomainDeviceDriveAddressParseXML(xmlNodePtr node,
+                                         virDomainDeviceDriveAddressPtr addr);
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 60962ee7c1..306926b64c 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -17385,6 +17385,8 @@ virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net)
+     bool MACAddrSpecified = !net->mac_generated;
+     bool PCIAddrSpecified = virDomainDeviceAddressIsValid(&net->info,
+                                                           VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI);
++    bool CCWAddrSpecified = virDomainDeviceAddressIsValid(&net->info,
++                                                          VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW);
+ 
+     for (i = 0; i < def->nnets; i++) {
+         if (MACAddrSpecified &&
+@@ -17396,9 +17398,14 @@ virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net)
+                                       &net->info.addr.pci))
+             continue;
+ 
++        if (CCWAddrSpecified &&
++            !virDomainDeviceCCWAddressEqual(&def->nets[i]->info.addr.ccw,
++                                            &net->info.addr.ccw))
++            continue;
++
+         if (matchidx >= 0) {
+             /* there were multiple matches on mac address, and no
+-             * qualifying guest-side PCI address was given, so we must
++             * qualifying guest-side PCI/CCW address was given, so we must
+              * fail (NB: a USB address isn't adequate, since it may
+              * specify only vendor and product ID, and there may be
+              * multiples of those.
+@@ -17428,6 +17435,14 @@ virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net)
+                            net->info.addr.pci.bus,
+                            net->info.addr.pci.slot,
+                            net->info.addr.pci.function);
++        } else if (MACAddrSpecified && CCWAddrSpecified) {
++            virReportError(VIR_ERR_DEVICE_MISSING,
++                           _("no device matching MAC address %s found on "
++                             VIR_CCW_DEVICE_ADDRESS_FMT),
++                           virMacAddrFormat(&net->mac, mac),
++                           net->info.addr.ccw.cssid,
++                           net->info.addr.ccw.ssid,
++                           net->info.addr.ccw.devno);
+         } else if (PCIAddrSpecified) {
+             virReportError(VIR_ERR_DEVICE_MISSING,
+                            _("no device found on " VIR_PCI_DEVICE_ADDRESS_FMT),
+@@ -17435,6 +17450,12 @@ virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net)
+                            net->info.addr.pci.bus,
+                            net->info.addr.pci.slot,
+                            net->info.addr.pci.function);
++        } else if (CCWAddrSpecified) {
++            virReportError(VIR_ERR_DEVICE_MISSING,
++                           _("no device found on " VIR_CCW_DEVICE_ADDRESS_FMT),
++                           net->info.addr.ccw.cssid,
++                           net->info.addr.ccw.ssid,
++                           net->info.addr.ccw.devno);
+         } else if (MACAddrSpecified) {
+             virReportError(VIR_ERR_DEVICE_MISSING,
+                            _("no device matching MAC address %s found"),
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 9e290c7bdf..130828706a 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -128,6 +128,7 @@ virDeviceInfoPCIAddressIsWanted;
+ virDomainDeviceAddressIsValid;
+ virDomainDeviceAddressTypeToString;
+ virDomainDeviceCcidAddressParseXML;
++virDomainDeviceCCWAddressEqual;
+ virDomainDeviceCCWAddressIsValid;
+ virDomainDeviceCCWAddressParseXML;
+ virDomainDeviceDriveAddressParseXML;
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-vircgroup-correctly-free-nested-virCgroupPtr.patch b/SOURCES/libvirt-vircgroup-correctly-free-nested-virCgroupPtr.patch
new file mode 100644
index 0000000..e72b84d
--- /dev/null
+++ b/SOURCES/libvirt-vircgroup-correctly-free-nested-virCgroupPtr.patch
@@ -0,0 +1,45 @@
+From 7cdf83f2e699a9c9b8cafbc09dbd21d2cb3a3b45 Mon Sep 17 00:00:00 2001
+Message-Id: <7cdf83f2e699a9c9b8cafbc09dbd21d2cb3a3b45@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Fri, 19 Feb 2021 13:34:01 +0100
+Subject: [PATCH] vircgroup: correctly free nested virCgroupPtr
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Fixes: 184245f53b94fc84f727eb6e8a2aa52df02d69c0
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 6a1f5e8a4f3184bb54b9dcaa3afcf8c97adccb62)
+
+Conflicts:
+    src/util/vircgroup.c
+        - missing upstream g_free rewrite
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <bc2f0207bc684ca81c45b6234a7aaba5227867d7.1613737828.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/vircgroup.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
+index d0f867ba7f..0a6404e97c 100644
+--- a/src/util/vircgroup.c
++++ b/src/util/vircgroup.c
+@@ -3711,7 +3711,8 @@ virCgroupFree(virCgroupPtr *group)
+     VIR_FREE((*group)->unified.mountPoint);
+     VIR_FREE((*group)->unified.placement);
+     VIR_FREE((*group)->unitName);
+-    VIR_FREE((*group)->nested);
++
++    virCgroupFree(&(*group)->nested);
+ 
+     VIR_FREE((*group)->path);
+     VIR_FREE(*group);
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-vircgroup-enforce-range-limit-for-cpu.shares.patch b/SOURCES/libvirt-vircgroup-enforce-range-limit-for-cpu.shares.patch
new file mode 100644
index 0000000..d800b77
--- /dev/null
+++ b/SOURCES/libvirt-vircgroup-enforce-range-limit-for-cpu.shares.patch
@@ -0,0 +1,147 @@
+From c82c32f60579d148f37064e5156e857fa3c84c2f Mon Sep 17 00:00:00 2001
+Message-Id: <c82c32f60579d148f37064e5156e857fa3c84c2f@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Thu, 4 Mar 2021 12:57:57 +0100
+Subject: [PATCH] vircgroup: enforce range limit for cpu.shares
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Before the conversion to using systemd DBus API to set the cpu.shares
+there was some magic conversion done by kernel which was documented in
+virsh manpage as well. Now systemd errors out if the value is out of
+range.
+
+Since we enforce the range for other cpu cgroup attributes 'quota' and
+'period' it makes sense to do the same for 'shares' as well.
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 1d9d9961ada6c2d0b9facae0ef8be4f459cf7fc9)
+
+Conflicts:
+    docs/formatdomain.rst
+    src/conf/domain_validate.c
+        - both are not present in downstream
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <79b9ef9f98b3ab35061f8c4e4acf7b6861d28055.1614858616.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/formatdomain.html.in |  1 +
+ docs/manpages/virsh.rst   |  5 +----
+ src/conf/domain_conf.c    | 10 ++++++++++
+ src/util/vircgroup.h      |  2 ++
+ src/util/vircgroupv1.c    | 10 ++++++++++
+ src/util/vircgroupv2.c    | 10 ++++++++++
+ 6 files changed, 34 insertions(+), 4 deletions(-)
+
+diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
+index 4341e256a8..7ac9523684 100644
+--- a/docs/formatdomain.html.in
++++ b/docs/formatdomain.html.in
+@@ -854,6 +854,7 @@
+         it's a relative measure based on the setting of other VM,
+         e.g. A VM configured with value
+         2048 will get twice as much CPU time as a VM configured with value 1024.
++        The value should be in range [2, 262144].
+         <span class="since">Since 0.9.0</span>
+       </dd>
+       <dt><code>period</code></dt>
+diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
+index a5b95c1123..01e1c01912 100644
+--- a/docs/manpages/virsh.rst
++++ b/docs/manpages/virsh.rst
+@@ -3704,10 +3704,7 @@ If *--live* is specified, set scheduler information of a running guest.
+ If *--config* is specified, affect the next boot of a persistent guest.
+ If *--current* is specified, affect the current guest state.
+ 
+-``Note``: The cpu_shares parameter has a valid value range of 0-262144; Negative
+-values are wrapped to positive, and larger values are capped at the maximum.
+-Therefore, -1 is a useful shorthand for 262144. On the Linux kernel, the
+-values 0 and 1 are automatically converted to a minimal value of 2.
++``Note``: The cpu_shares parameter has a valid value range of 2-262144.
+ 
+ ``Note``: The weight and cap parameters are defined only for the
+ XEN_CREDIT scheduler.
+diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
+index 9f6cdb0de8..444657c9a1 100644
+--- a/src/conf/domain_conf.c
++++ b/src/conf/domain_conf.c
+@@ -7026,6 +7026,16 @@ virDomainDefLifecycleActionValidate(const virDomainDef *def)
+ static int
+ virDomainDefCputuneValidate(const virDomainDef *def)
+ {
++    if (def->cputune.shares > 0 &&
++        (def->cputune.shares < VIR_CGROUP_CPU_SHARES_MIN ||
++         def->cputune.shares > VIR_CGROUP_CPU_SHARES_MAX)) {
++        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
++                       _("Value of cputune 'shares' must be in range [%llu, %llu]"),
++                         VIR_CGROUP_CPU_SHARES_MIN,
++                         VIR_CGROUP_CPU_SHARES_MAX);
++        return -1;
++    }
++
+     CPUTUNE_VALIDATE_PERIOD(period);
+     CPUTUNE_VALIDATE_PERIOD(global_period);
+     CPUTUNE_VALIDATE_PERIOD(emulator_period);
+diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
+index 1c6edea0be..938cfdfbe3 100644
+--- a/src/util/vircgroup.h
++++ b/src/util/vircgroup.h
+@@ -243,6 +243,8 @@ virCgroupGetDomainTotalCpuStats(virCgroupPtr group,
+ int virCgroupSetCpuShares(virCgroupPtr group, unsigned long long shares);
+ int virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares);
+ 
++#define VIR_CGROUP_CPU_SHARES_MIN 2LL
++#define VIR_CGROUP_CPU_SHARES_MAX 262144LL
+ #define VIR_CGROUP_CPU_PERIOD_MIN 1000LL
+ #define VIR_CGROUP_CPU_PERIOD_MAX 1000000LL
+ #define VIR_CGROUP_CPU_QUOTA_MIN 1000LL
+diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c
+index 49a2cb023e..d417446447 100644
+--- a/src/util/vircgroupv1.c
++++ b/src/util/vircgroupv1.c
+@@ -1901,6 +1901,16 @@ static int
+ virCgroupV1SetCpuShares(virCgroupPtr group,
+                         unsigned long long shares)
+ {
++    if (shares < VIR_CGROUP_CPU_SHARES_MIN ||
++        shares > VIR_CGROUP_CPU_SHARES_MAX) {
++        virReportError(VIR_ERR_INVALID_ARG,
++                       _("shares '%llu' must be in range [%llu, %llu]"),
++                       shares,
++                       VIR_CGROUP_CPU_SHARES_MIN,
++                       VIR_CGROUP_CPU_SHARES_MAX);
++        return -1;
++    }
++
+     if (group->unitName) {
+         return virCgroupSetValueDBus(group->unitName, "CPUShares",
+                                      "t", shares);
+diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
+index a14fc669fb..079fe6a8ec 100644
+--- a/src/util/vircgroupv2.c
++++ b/src/util/vircgroupv2.c
+@@ -1499,6 +1499,16 @@ static int
+ virCgroupV2SetCpuShares(virCgroupPtr group,
+                         unsigned long long shares)
+ {
++    if (shares < VIR_CGROUP_CPU_SHARES_MIN ||
++        shares > VIR_CGROUP_CPU_SHARES_MAX) {
++        virReportError(VIR_ERR_INVALID_ARG,
++                       _("shares '%llu' must be in range [%llu, %llu]"),
++                       shares,
++                       VIR_CGROUP_CPU_SHARES_MIN,
++                       VIR_CGROUP_CPU_SHARES_MAX);
++        return -1;
++    }
++
+     if (group->unitName) {
+         return virCgroupSetValueDBus(group->unitName, "CPUWeight",
+                                      "t", shares);
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-vircgroup-fix-cpu-quota-maximum-limit.patch b/SOURCES/libvirt-vircgroup-fix-cpu-quota-maximum-limit.patch
new file mode 100644
index 0000000..c744ed7
--- /dev/null
+++ b/SOURCES/libvirt-vircgroup-fix-cpu-quota-maximum-limit.patch
@@ -0,0 +1,45 @@
+From 92b7a56b1a23d1cf39e810a58a6d7d0b1f500e69 Mon Sep 17 00:00:00 2001
+Message-Id: <92b7a56b1a23d1cf39e810a58a6d7d0b1f500e69@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Thu, 21 Jan 2021 10:24:06 -0300
+Subject: [PATCH] vircgroup: fix cpu quota maximum limit
+
+Kernel commit <d505b8af58912ae1e1a211fabc9995b19bd40828> added proper
+check for cpu quota maximum limit to prevent internal overflow.
+
+Even though this change is not present in all kernels it makes sense
+to enforce the same limit in libvirt.
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1750315
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit ed1ba69f5a8132f8c1e73d2a1f142d70de0b564a)
+
+https://bugzilla.redhat.com/1915733
+
+Signed-off-by: Daniel Henrique Barboza <dbarboza@redhat.com>
+Message-Id: <20210121132406.337681-5-dbarboza@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+---
+ src/util/vircgroup.h | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
+index 83fa74840f..1c6edea0be 100644
+--- a/src/util/vircgroup.h
++++ b/src/util/vircgroup.h
+@@ -246,7 +246,9 @@ int virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares);
+ #define VIR_CGROUP_CPU_PERIOD_MIN 1000LL
+ #define VIR_CGROUP_CPU_PERIOD_MAX 1000000LL
+ #define VIR_CGROUP_CPU_QUOTA_MIN 1000LL
+-#define VIR_CGROUP_CPU_QUOTA_MAX 18446744073709551LL
++/* Based on kernel code ((1ULL << MAX_BW_BITS) - 1) where MAX_BW_BITS is
++ * (64 - BW_SHIFT) and BW_SHIFT is 20 */
++#define VIR_CGROUP_CPU_QUOTA_MAX 17592186044415LL
+ 
+ int virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period);
+ int virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period);
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-vircgroup-introduce-nested-cgroup-to-properly-work-with-systemd.patch b/SOURCES/libvirt-vircgroup-introduce-nested-cgroup-to-properly-work-with-systemd.patch
new file mode 100644
index 0000000..435dc6a
--- /dev/null
+++ b/SOURCES/libvirt-vircgroup-introduce-nested-cgroup-to-properly-work-with-systemd.patch
@@ -0,0 +1,879 @@
+From 2593f2e4626fbb6dfef2317bceea4d1b8275f9d8 Mon Sep 17 00:00:00 2001
+Message-Id: <2593f2e4626fbb6dfef2317bceea4d1b8275f9d8@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Fri, 19 Feb 2021 13:33:59 +0100
+Subject: [PATCH] vircgroup: introduce nested cgroup to properly work with
+ systemd
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When running on host with systemd we register VMs with machined.
+In this case systemd creates the root VM cgroup for us. This has some
+implications where one of them is that systemd owns all files inside
+the root VM cgroup and we should not touch them.
+
+We already use DBus calls for some of the APIs but for the remaining
+ones we will continue accessing the files directly. Systemd doesn't
+support threaded cgroups so we need to do this.
+
+The reason why we don't use DBus for most of the APIs is that we already
+have a code that works with files and we would have to check if systemd
+supports each API.
+
+This change introduces new topology on systemd hosts:
+
+$ROOT
+  |
+  +- machine.slice
+     |
+     +- machine-qemu\x2d1\x2dvm1.scope
+        |
+        +- libvirt
+           |
+           +- emulator
+           +- vcpu0
+           +- vcpu0
+
+compared to the previous topology:
+
+$ROOT
+  |
+  +- machine.slice
+     |
+     +- machine-qemu\x2d1\x2dvm1.scope
+        |
+        +- emulator
+        +- vcpu0
+        +- vcpu0
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 184245f53b94fc84f727eb6e8a2aa52df02d69c0)
+
+Conflicts:
+    src/util/vircgroup.c
+        - missing upstream g_free and g_autofree rewrite
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <51312c8b520e4ed794f8cd8a77b77c228387bb15.1613737828.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ docs/cgroups.html.in     |  29 +++--
+ src/util/vircgroup.c     | 256 +++++++++++++++++++++++++++++++--------
+ src/util/vircgrouppriv.h |   4 +
+ src/util/vircgroupv1.c   |  15 ++-
+ src/util/vircgroupv2.c   |   6 +
+ 5 files changed, 245 insertions(+), 65 deletions(-)
+
+diff --git a/docs/cgroups.html.in b/docs/cgroups.html.in
+index 78dede1bba..412a9360ff 100644
+--- a/docs/cgroups.html.in
++++ b/docs/cgroups.html.in
+@@ -117,21 +117,27 @@ $ROOT
+       |
+       +- machine-qemu\x2d1\x2dvm1.scope
+       |   |
+-      |   +- emulator
+-      |   +- vcpu0
+-      |   +- vcpu1
++      |   +- libvirt
++      |       |
++      |       +- emulator
++      |       +- vcpu0
++      |       +- vcpu1
+       |
+       +- machine-qemu\x2d2\x2dvm2.scope
+       |   |
+-      |   +- emulator
+-      |   +- vcpu0
+-      |   +- vcpu1
++      |   +- libvirt
++      |       |
++      |       +- emulator
++      |       +- vcpu0
++      |       +- vcpu1
+       |
+       +- machine-qemu\x2d3\x2dvm3.scope
+       |   |
+-      |   +- emulator
+-      |   +- vcpu0
+-      |   +- vcpu1
++      |   +- libvirt
++      |       |
++      |       +- emulator
++      |       +- vcpu0
++      |       +- vcpu1
+       |
+       +- machine-engineering.slice
+       |   |
+@@ -148,6 +154,11 @@ $ROOT
+           +- machine-lxc\x2d33333\x2dcontainer3.scope
+     </pre>
+ 
++    <p>
++      Prior libvirt 7.1.0 the topology doesn't have extra
++      <code>libvirt</code> directory.
++    </p>
++
+     <h3><a id="currentLayoutGeneric">Non-systemd cgroups layout</a></h3>
+ 
+     <p>
+diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
+index 8f5bcd94f4..d0f867ba7f 100644
+--- a/src/util/vircgroup.c
++++ b/src/util/vircgroup.c
+@@ -639,6 +639,22 @@ virCgroupMakeGroup(virCgroupPtr parent,
+ }
+ 
+ 
++static bool
++virCgroupExists(virCgroupPtr group)
++{
++    size_t i;
++
++    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
++        if (group->backends[i] &&
++            !group->backends[i]->exists(group)) {
++            return false;
++        }
++    }
++
++    return true;
++}
++
++
+ /**
+  * virCgroupNew:
+  * @path: path for the new group
+@@ -695,10 +711,11 @@ virCgroupAddTaskInternal(virCgroupPtr group,
+                          unsigned int flags)
+ {
+     size_t i;
++    virCgroupPtr parent = virCgroupGetNested(group);
+ 
+     for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
+-        if (group->backends[i] &&
+-            group->backends[i]->addTask(group, pid, flags) < 0) {
++        if (parent->backends[i] &&
++            parent->backends[i]->addTask(parent, pid, flags) < 0) {
+             return -1;
+         }
+     }
+@@ -871,6 +888,30 @@ virCgroupNewPartition(const char *path,
+ }
+ 
+ 
++static int
++virCgroupNewNested(virCgroupPtr parent,
++                   int controllers,
++                   bool create,
++                   pid_t pid,
++                   virCgroupPtr *nested)
++{
++    virCgroupPtr new = NULL;
++
++    if (virCgroupNew(-1, "libvirt", parent, controllers, &new) < 0)
++        return -1;
++
++    if (create) {
++        if (virCgroupMakeGroup(parent, new, create, pid, VIR_CGROUP_NONE) < 0) {
++            virCgroupFree(&new);
++            return -1;
++        }
++    }
++
++    *nested = g_steal_pointer(&new);
++    return 0;
++}
++
++
+ /**
+ * virCgroupNewSelf:
+ *
+@@ -954,6 +995,7 @@ virCgroupNewThread(virCgroupPtr domain,
+                    virCgroupPtr *group)
+ {
+     g_autofree char *name = NULL;
++    virCgroupPtr parent = NULL;
+     int controllers;
+ 
+     switch (nameval) {
+@@ -976,10 +1018,12 @@ virCgroupNewThread(virCgroupPtr domain,
+                    (1 << VIR_CGROUP_CONTROLLER_CPUACCT) |
+                    (1 << VIR_CGROUP_CONTROLLER_CPUSET));
+ 
+-    if (virCgroupNew(-1, name, domain, controllers, group) < 0)
++    parent = virCgroupGetNested(domain);
++
++    if (virCgroupNew(-1, name, parent, controllers, group) < 0)
+         return -1;
+ 
+-    if (virCgroupMakeGroup(domain, *group, create, -1, VIR_CGROUP_THREAD) < 0) {
++    if (virCgroupMakeGroup(parent, *group, create, -1, VIR_CGROUP_THREAD) < 0) {
+         virCgroupFree(group);
+         return -1;
+     }
+@@ -1009,6 +1053,7 @@ virCgroupNewDetectMachine(const char *name,
+                           virCgroupPtr *group)
+ {
+     size_t i;
++    virCgroupPtr nested = NULL;
+ 
+     if (virCgroupNewDetect(pid, controllers, group) < 0) {
+         if (virCgroupNewIgnoreError())
+@@ -1032,6 +1077,14 @@ virCgroupNewDetectMachine(const char *name,
+     if (virSystemdHasMachined() == 0 && !(*group)->unitName)
+         return -1;
+ 
++    if (virCgroupNewNested((*group), controllers, false, -1, &nested) < 0)
++        return -1;
++
++    if (virCgroupExists(nested))
++        (*group)->nested = g_steal_pointer(&nested);
++
++    virCgroupFree(&nested);
++
+     return 0;
+ }
+ 
+@@ -1107,6 +1160,7 @@ virCgroupNewMachineSystemd(const char *name,
+ {
+     int rv;
+     virCgroupPtr init;
++    virCgroupPtr nested = NULL;
+     g_autofree char *path = NULL;
+     size_t i;
+ 
+@@ -1157,6 +1211,13 @@ virCgroupNewMachineSystemd(const char *name,
+         return -1;
+     }
+ 
++    if (virCgroupNewNested((*group), controllers, true, pidleader, &nested) < 0) {
++        virCgroupFree(group);
++        return -1;
++    }
++
++    (*group)->nested = nested;
++
+     if (virCgroupAddProcess(*group, pidleader) < 0) {
+         virErrorPtr saved;
+ 
+@@ -1349,7 +1410,9 @@ virCgroupGetBlkioIoServiced(virCgroupPtr group,
+                             long long *requests_read,
+                             long long *requests_write)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO,
+                             getBlkioIoServiced, -1,
+                             bytes_read, bytes_write,
+                             requests_read, requests_write);
+@@ -1376,7 +1439,9 @@ virCgroupGetBlkioIoDeviceServiced(virCgroupPtr group,
+                                   long long *requests_read,
+                                   long long *requests_write)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO,
+                             getBlkioIoDeviceServiced, -1,
+                             path, bytes_read, bytes_write,
+                             requests_read, requests_write);
+@@ -1427,7 +1492,9 @@ virCgroupSetBlkioDeviceReadIops(virCgroupPtr group,
+                                 const char *path,
+                                 unsigned int riops)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO,
+                             setBlkioDeviceReadIops, -1, path, riops);
+ }
+ 
+@@ -1445,7 +1512,9 @@ virCgroupSetBlkioDeviceWriteIops(virCgroupPtr group,
+                                  const char *path,
+                                  unsigned int wiops)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO,
+                             setBlkioDeviceWriteIops, -1, path, wiops);
+ }
+ 
+@@ -1463,7 +1532,9 @@ virCgroupSetBlkioDeviceReadBps(virCgroupPtr group,
+                                const char *path,
+                                unsigned long long rbps)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO,
+                             setBlkioDeviceReadBps, -1, path, rbps);
+ }
+ 
+@@ -1480,7 +1551,9 @@ virCgroupSetBlkioDeviceWriteBps(virCgroupPtr group,
+                                 const char *path,
+                                 unsigned long long wbps)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO,
+                             setBlkioDeviceWriteBps, -1, path, wbps);
+ }
+ 
+@@ -1516,7 +1589,9 @@ virCgroupGetBlkioDeviceReadIops(virCgroupPtr group,
+                                 const char *path,
+                                 unsigned int *riops)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO,
+                             getBlkioDeviceReadIops, -1, path, riops);
+ }
+ 
+@@ -1533,7 +1608,9 @@ virCgroupGetBlkioDeviceWriteIops(virCgroupPtr group,
+                                  const char *path,
+                                  unsigned int *wiops)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO,
+                             getBlkioDeviceWriteIops, -1, path, wiops);
+ }
+ 
+@@ -1550,7 +1627,9 @@ virCgroupGetBlkioDeviceReadBps(virCgroupPtr group,
+                                const char *path,
+                                unsigned long long *rbps)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO,
+                             getBlkioDeviceReadBps, -1, path, rbps);
+ }
+ 
+@@ -1567,7 +1646,9 @@ virCgroupGetBlkioDeviceWriteBps(virCgroupPtr group,
+                                 const char *path,
+                                 unsigned long long *wbps)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO,
+                             getBlkioDeviceWriteBps, -1, path, wbps);
+ }
+ 
+@@ -1600,7 +1681,9 @@ virCgroupGetBlkioDeviceWeight(virCgroupPtr group,
+ int
+ virCgroupSetMemory(virCgroupPtr group, unsigned long long kb)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY,
+                             setMemory, -1, kb);
+ }
+ 
+@@ -1627,7 +1710,9 @@ virCgroupGetMemoryStat(virCgroupPtr group,
+                        unsigned long long *inactiveFile,
+                        unsigned long long *unevictable)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY,
+                             getMemoryStat, -1, cache,
+                             activeAnon, inactiveAnon,
+                             activeFile, inactiveFile,
+@@ -1646,7 +1731,9 @@ virCgroupGetMemoryStat(virCgroupPtr group,
+ int
+ virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY,
+                             getMemoryUsage, -1, kb);
+ }
+ 
+@@ -1662,7 +1749,9 @@ virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb)
+ int
+ virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY,
+                             setMemoryHardLimit, -1, kb);
+ }
+ 
+@@ -1678,7 +1767,9 @@ virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb)
+ int
+ virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY,
+                             getMemoryHardLimit, -1, kb);
+ }
+ 
+@@ -1694,7 +1785,9 @@ virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb)
+ int
+ virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY,
+                             setMemorySoftLimit, -1, kb);
+ }
+ 
+@@ -1710,7 +1803,9 @@ virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb)
+ int
+ virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY,
+                             getMemorySoftLimit, -1, kb);
+ }
+ 
+@@ -1726,7 +1821,9 @@ virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb)
+ int
+ virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY,
+                             setMemSwapHardLimit, -1, kb);
+ }
+ 
+@@ -1742,7 +1839,9 @@ virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb)
+ int
+ virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY,
+                             getMemSwapHardLimit, -1, kb);
+ }
+ 
+@@ -1758,7 +1857,9 @@ virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb)
+ int
+ virCgroupGetMemSwapUsage(virCgroupPtr group, unsigned long long *kb)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY,
+                             getMemSwapUsage, -1, kb);
+ }
+ 
+@@ -1774,7 +1875,9 @@ virCgroupGetMemSwapUsage(virCgroupPtr group, unsigned long long *kb)
+ int
+ virCgroupSetCpusetMems(virCgroupPtr group, const char *mems)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUSET,
+                             setCpusetMems, -1, mems);
+ }
+ 
+@@ -1790,7 +1893,9 @@ virCgroupSetCpusetMems(virCgroupPtr group, const char *mems)
+ int
+ virCgroupGetCpusetMems(virCgroupPtr group, char **mems)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUSET,
+                             getCpusetMems, -1, mems);
+ }
+ 
+@@ -1806,7 +1911,9 @@ virCgroupGetCpusetMems(virCgroupPtr group, char **mems)
+ int
+ virCgroupSetCpusetMemoryMigrate(virCgroupPtr group, bool migrate)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUSET,
+                             setCpusetMemoryMigrate, -1, migrate);
+ }
+ 
+@@ -1822,7 +1929,9 @@ virCgroupSetCpusetMemoryMigrate(virCgroupPtr group, bool migrate)
+ int
+ virCgroupGetCpusetMemoryMigrate(virCgroupPtr group, bool *migrate)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUSET,
+                             getCpusetMemoryMigrate, -1, migrate);
+ }
+ 
+@@ -1838,7 +1947,9 @@ virCgroupGetCpusetMemoryMigrate(virCgroupPtr group, bool *migrate)
+ int
+ virCgroupSetCpusetCpus(virCgroupPtr group, const char *cpus)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUSET,
+                             setCpusetCpus, -1, cpus);
+ }
+ 
+@@ -1854,7 +1965,9 @@ virCgroupSetCpusetCpus(virCgroupPtr group, const char *cpus)
+ int
+ virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUSET,
+                             getCpusetCpus, -1, cpus);
+ }
+ 
+@@ -1869,7 +1982,9 @@ virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus)
+ int
+ virCgroupDenyAllDevices(virCgroupPtr group)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_DEVICES,
+                             denyAllDevices, -1);
+ }
+ 
+@@ -1890,7 +2005,9 @@ virCgroupDenyAllDevices(virCgroupPtr group)
+ int
+ virCgroupAllowAllDevices(virCgroupPtr group, int perms)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_DEVICES,
+                             allowAllDevices, -1, perms);
+ }
+ 
+@@ -1910,7 +2027,9 @@ int
+ virCgroupAllowDevice(virCgroupPtr group, char type, int major, int minor,
+                      int perms)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_DEVICES,
+                             allowDevice, -1, type, major, minor, perms);
+ }
+ 
+@@ -1936,6 +2055,7 @@ virCgroupAllowDevicePath(virCgroupPtr group,
+                          bool ignoreEacces)
+ {
+     struct stat sb;
++    virCgroupPtr parent = virCgroupGetNested(group);
+ 
+     if (stat(path, &sb) < 0) {
+         if (errno == EACCES && ignoreEacces)
+@@ -1950,7 +2070,7 @@ virCgroupAllowDevicePath(virCgroupPtr group,
+     if (!S_ISCHR(sb.st_mode) && !S_ISBLK(sb.st_mode))
+         return 1;
+ 
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES,
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_DEVICES,
+                             allowDevice, -1,
+                             S_ISCHR(sb.st_mode) ? 'c' : 'b',
+                             major(sb.st_rdev),
+@@ -1974,7 +2094,9 @@ int
+ virCgroupDenyDevice(virCgroupPtr group, char type, int major, int minor,
+                     int perms)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_DEVICES,
+                             denyDevice, -1, type, major, minor, perms);
+ }
+ 
+@@ -2000,6 +2122,7 @@ virCgroupDenyDevicePath(virCgroupPtr group,
+                         bool ignoreEacces)
+ {
+     struct stat sb;
++    virCgroupPtr parent = virCgroupGetNested(group);
+ 
+     if (stat(path, &sb) < 0) {
+         if (errno == EACCES && ignoreEacces)
+@@ -2014,7 +2137,7 @@ virCgroupDenyDevicePath(virCgroupPtr group,
+     if (!S_ISCHR(sb.st_mode) && !S_ISBLK(sb.st_mode))
+         return 1;
+ 
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES,
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_DEVICES,
+                             denyDevice, -1,
+                             S_ISCHR(sb.st_mode) ? 'c' : 'b',
+                             major(sb.st_rdev),
+@@ -2282,7 +2405,9 @@ virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares)
+ int
+ virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPU,
+                             setCpuCfsPeriod, -1, cfs_period);
+ }
+ 
+@@ -2298,7 +2423,9 @@ virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period)
+ int
+ virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPU,
+                             getCpuCfsPeriod, -1, cfs_period);
+ }
+ 
+@@ -2315,7 +2442,9 @@ virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period)
+ int
+ virCgroupSetCpuCfsQuota(virCgroupPtr group, long long cfs_quota)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPU,
+                             setCpuCfsQuota, -1, cfs_quota);
+ }
+ 
+@@ -2323,7 +2452,9 @@ virCgroupSetCpuCfsQuota(virCgroupPtr group, long long cfs_quota)
+ int
+ virCgroupGetCpuacctPercpuUsage(virCgroupPtr group, char **usage)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUACCT,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUACCT,
+                             getCpuacctPercpuUsage, -1, usage);
+ }
+ 
+@@ -2669,7 +2800,9 @@ virCgroupKillPainfully(virCgroupPtr group)
+ int
+ virCgroupGetCpuCfsQuota(virCgroupPtr group, long long *cfs_quota)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPU,
+                             getCpuCfsQuota, -1, cfs_quota);
+ }
+ 
+@@ -2677,7 +2810,9 @@ virCgroupGetCpuCfsQuota(virCgroupPtr group, long long *cfs_quota)
+ int
+ virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUACCT,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUACCT,
+                             getCpuacctUsage, -1, usage);
+ }
+ 
+@@ -2686,7 +2821,9 @@ int
+ virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user,
+                         unsigned long long *sys)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUACCT,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUACCT,
+                             getCpuacctStat, -1, user, sys);
+ }
+ 
+@@ -2694,7 +2831,9 @@ virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user,
+ int
+ virCgroupSetFreezerState(virCgroupPtr group, const char *state)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_FREEZER,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_FREEZER,
+                             setFreezerState, -1, state);
+ }
+ 
+@@ -2702,7 +2841,9 @@ virCgroupSetFreezerState(virCgroupPtr group, const char *state)
+ int
+ virCgroupGetFreezerState(virCgroupPtr group, char **state)
+ {
+-    VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_FREEZER,
++    virCgroupPtr parent = virCgroupGetNested(group);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_FREEZER,
+                             getFreezerState, -1, state);
+ }
+ 
+@@ -2712,10 +2853,11 @@ virCgroupBindMount(virCgroupPtr group, const char *oldroot,
+                    const char *mountopts)
+ {
+     size_t i;
++    virCgroupPtr parent = virCgroupGetNested(group);
+ 
+     for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
+-        if (group->backends[i] &&
+-            group->backends[i]->bindMount(group, oldroot, mountopts) < 0) {
++        if (parent->backends[i] &&
++            parent->backends[i]->bindMount(parent, oldroot, mountopts) < 0) {
+             return -1;
+         }
+     }
+@@ -2730,10 +2872,11 @@ int virCgroupSetOwner(virCgroupPtr cgroup,
+                       int controllers)
+ {
+     size_t i;
++    virCgroupPtr parent = virCgroupGetNested(cgroup);
+ 
+     for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
+-        if (cgroup->backends[i] &&
+-            cgroup->backends[i]->setOwner(cgroup, uid, gid, controllers) < 0) {
++        if (parent->backends[i] &&
++            parent->backends[i]->setOwner(parent, uid, gid, controllers) < 0) {
+             return -1;
+         }
+     }
+@@ -2752,7 +2895,9 @@ int virCgroupSetOwner(virCgroupPtr cgroup,
+ bool
+ virCgroupSupportsCpuBW(virCgroupPtr cgroup)
+ {
+-    VIR_CGROUP_BACKEND_CALL(cgroup, VIR_CGROUP_CONTROLLER_CPU,
++    virCgroupPtr parent = virCgroupGetNested(cgroup);
++
++    VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPU,
+                             supportsCpuBW, false);
+ }
+ 
+@@ -2760,10 +2905,11 @@ int
+ virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller)
+ {
+     size_t i;
++    virCgroupPtr parent = virCgroupGetNested(cgroup);
+ 
+     for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
+-        if (cgroup->backends[i]) {
+-            int rc = cgroup->backends[i]->hasEmptyTasks(cgroup, controller);
++        if (parent->backends[i]) {
++            int rc = parent->backends[i]->hasEmptyTasks(parent, controller);
+             if (rc <= 0)
+                 return rc;
+         }
+@@ -3565,6 +3711,7 @@ virCgroupFree(virCgroupPtr *group)
+     VIR_FREE((*group)->unified.mountPoint);
+     VIR_FREE((*group)->unified.placement);
+     VIR_FREE((*group)->unitName);
++    VIR_FREE((*group)->nested);
+ 
+     VIR_FREE((*group)->path);
+     VIR_FREE(*group);
+@@ -3577,9 +3724,12 @@ virCgroupDelThread(virCgroupPtr cgroup,
+                    int idx)
+ {
+     virCgroupPtr new_cgroup = NULL;
++    virCgroupPtr parent = NULL;
+ 
+     if (cgroup) {
+-        if (virCgroupNewThread(cgroup, nameval, idx, false, &new_cgroup) < 0)
++        parent = virCgroupGetNested(cgroup);
++
++        if (virCgroupNewThread(parent, nameval, idx, false, &new_cgroup) < 0)
+             return -1;
+ 
+         /* Remove the offlined cgroup */
+diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h
+index b4a9e0b379..104d74e4d7 100644
+--- a/src/util/vircgrouppriv.h
++++ b/src/util/vircgrouppriv.h
+@@ -69,8 +69,12 @@ struct _virCgroup {
+     virCgroupV2Controller unified;
+ 
+     char *unitName;
++    virCgroupPtr nested;
+ };
+ 
++#define virCgroupGetNested(cgroup) \
++    (cgroup->nested ? cgroup->nested : cgroup)
++
+ #define virCgroupSetValueDBus(unitName, key, ...) \
+     ({ \
+         int __ret = -1; \
+diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c
+index 57d617cb69..49a2cb023e 100644
+--- a/src/util/vircgroupv1.c
++++ b/src/util/vircgroupv1.c
+@@ -338,6 +338,8 @@ virCgroupV1DetectPlacement(virCgroupPtr group,
+ 
+     for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
+         const char *typestr = virCgroupV1ControllerTypeToString(i);
++        g_autofree char* placement = NULL;
++        char *tmp = NULL;
+ 
+         if (!virCgroupV1MountOptsMatchController(controllers, typestr))
+             continue;
+@@ -348,17 +350,24 @@ virCgroupV1DetectPlacement(virCgroupPtr group,
+         if (group->legacy[i].placement)
+             continue;
+ 
++        /* On systemd we create a nested cgroup for some cgroup tasks
++         * but the placement should point to the root cgroup. */
++        placement = g_strdup(selfpath);
++        tmp = g_strrstr(placement, "/libvirt");
++        if (tmp)
++            *tmp = '\0';
++
+         /*
+          * selfpath == "/" + path="" -> "/"
+          * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service"
+          * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo"
+          */
+         if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) {
+-            group->legacy[i].placement = g_strdup(selfpath);
++            group->legacy[i].placement = g_strdup(placement);
+         } else {
+-            bool delim = STREQ(selfpath, "/") || STREQ(path, "");
++            bool delim = STREQ(placement, "/") || STREQ(path, "");
+ 
+-            group->legacy[i].placement = g_strdup_printf("%s%s%s", selfpath,
++            group->legacy[i].placement = g_strdup_printf("%s%s%s", placement,
+                                                          delim ? "" : "/",
+                                                          path);
+         }
+diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
+index d15e2354cf..a14fc669fb 100644
+--- a/src/util/vircgroupv2.c
++++ b/src/util/vircgroupv2.c
+@@ -210,6 +210,12 @@ virCgroupV2DetectPlacement(virCgroupPtr group,
+     if (tmp)
+         *tmp = '\0';
+ 
++    /* On systemd we create a nested cgroup for some cgroup tasks
++     * but the placement should point to the root cgroup. */
++    tmp = g_strrstr(placement, "/libvirt");
++    if (tmp)
++        *tmp = '\0';
++
+     /*
+      * selfpath == "/" + path="" -> "/"
+      * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service"
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV1Exists-and-virCgroupV2Exists.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV1Exists-and-virCgroupV2Exists.patch
new file mode 100644
index 0000000..c73bf43
--- /dev/null
+++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV1Exists-and-virCgroupV2Exists.patch
@@ -0,0 +1,129 @@
+From f835b834d7922bed1ccda35885e42ab7c3f4a70f Mon Sep 17 00:00:00 2001
+Message-Id: <f835b834d7922bed1ccda35885e42ab7c3f4a70f@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Fri, 19 Feb 2021 13:33:58 +0100
+Subject: [PATCH] vircgroup: introduce virCgroupV1Exists and virCgroupV2Exists
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This will check if the cgroup actually exists on the system.
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit badc2bcc7398d8c0a739998a80411ddebf129512)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <14297ed923f0f23cc52506e61e637c8f45e331ee.1613737828.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/vircgroupbackend.h |  4 ++++
+ src/util/vircgroupv1.c      | 27 +++++++++++++++++++++++++++
+ src/util/vircgroupv2.c      | 15 +++++++++++++++
+ 3 files changed, 46 insertions(+)
+
+diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h
+index ac7b3ae517..dabc7bd4b4 100644
+--- a/src/util/vircgroupbackend.h
++++ b/src/util/vircgroupbackend.h
+@@ -115,6 +115,9 @@ typedef int
+                                const char *key,
+                                char **path);
+ 
++typedef bool
++(*virCgroupExistsCB)(virCgroupPtr group);
++
+ typedef int
+ (*virCgroupMakeGroupCB)(virCgroupPtr parent,
+                         virCgroupPtr group,
+@@ -378,6 +381,7 @@ struct _virCgroupBackend {
+     virCgroupGetAnyControllerCB getAnyController;
+     virCgroupPathOfControllerCB pathOfController;
+     virCgroupMakeGroupCB makeGroup;
++    virCgroupExistsCB exists;
+     virCgroupRemoveCB remove;
+     virCgroupAddTaskCB addTask;
+     virCgroupHasEmptyTasksCB hasEmptyTasks;
+diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c
+index eb2b611cee..57d617cb69 100644
+--- a/src/util/vircgroupv1.c
++++ b/src/util/vircgroupv1.c
+@@ -670,6 +670,32 @@ virCgroupV1MakeGroup(virCgroupPtr parent,
+ }
+ 
+ 
++static bool
++virCgroupV1Exists(virCgroupPtr group)
++{
++    size_t i;
++
++    for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
++        g_autofree char *path = NULL;
++
++        if (i == VIR_CGROUP_CONTROLLER_SYSTEMD)
++            continue;
++
++        if (!group->legacy[i].mountPoint)
++            continue;
++
++        if (virCgroupV1PathOfController(group, i, "", &path) < 0)
++            return false;
++
++        if (!virFileExists(path)) {
++            return false;
++        }
++    }
++
++    return true;
++}
++
++
+ static int
+ virCgroupV1Remove(virCgroupPtr group)
+ {
+@@ -2136,6 +2162,7 @@ virCgroupBackend virCgroupV1Backend = {
+     .getAnyController = virCgroupV1GetAnyController,
+     .pathOfController = virCgroupV1PathOfController,
+     .makeGroup = virCgroupV1MakeGroup,
++    .exists = virCgroupV1Exists,
+     .remove = virCgroupV1Remove,
+     .addTask = virCgroupV1AddTask,
+     .hasEmptyTasks = virCgroupV1HasEmptyTasks,
+diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
+index 5e19ed8332..d15e2354cf 100644
+--- a/src/util/vircgroupv2.c
++++ b/src/util/vircgroupv2.c
+@@ -493,6 +493,20 @@ virCgroupV2MakeGroup(virCgroupPtr parent,
+ }
+ 
+ 
++static bool
++virCgroupV2Exists(virCgroupPtr group)
++{
++    g_autofree char *path = NULL;
++    int controller;
++
++    controller = virCgroupV2GetAnyController(group);
++    if (virCgroupV2PathOfController(group, controller, "", &path) < 0)
++        return false;
++
++    return virFileExists(path);
++}
++
++
+ static int
+ virCgroupV2Remove(virCgroupPtr group)
+ {
+@@ -1886,6 +1900,7 @@ virCgroupBackend virCgroupV2Backend = {
+     .getAnyController = virCgroupV2GetAnyController,
+     .pathOfController = virCgroupV2PathOfController,
+     .makeGroup = virCgroupV2MakeGroup,
++    .exists = virCgroupV2Exists,
+     .remove = virCgroupV2Remove,
+     .addTask = virCgroupV2AddTask,
+     .hasEmptyTasks = virCgroupV2HasEmptyTasks,
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-vircgroup-use-DBus-call-to-systemd-for-some-APIs.patch b/SOURCES/libvirt-vircgroup-use-DBus-call-to-systemd-for-some-APIs.patch
new file mode 100644
index 0000000..8d300b3
--- /dev/null
+++ b/SOURCES/libvirt-vircgroup-use-DBus-call-to-systemd-for-some-APIs.patch
@@ -0,0 +1,310 @@
+From 205289d2792aacf68ed2cb8563d1860bd36137a0 Mon Sep 17 00:00:00 2001
+Message-Id: <205289d2792aacf68ed2cb8563d1860bd36137a0@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Fri, 19 Feb 2021 13:33:55 +0100
+Subject: [PATCH] vircgroup: use DBus call to systemd for some APIs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When running on host with systemd we register VMs with machined.
+In this case systemd creates the root VM cgroup for us. This has some
+implications where one of them is that systemd owns all files inside
+the root VM cgroup and we should not touch them.
+
+If we change any value in file that systemd knows about it will be
+changed to what systemd thinks it should be when executing
+`systemctl daemon-reload`.
+
+These are the APIs that we need to call using systemd because they set
+limits that are proportional to sibling cgroups.
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 9c1693eff427661616ce1bd2795688f87288a412)
+
+Conflicts:
+    src/util/vircgroup.c
+        - missing upstream g_autofree rewrite
+        - missing upstream glib dbus rewrite, hence the ugly macro
+          instead of a function
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <5d22d307112333f1da565cb642ea9001a7b8b55b.1613737828.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/vircgroup.c     | 11 ++++++++++
+ src/util/vircgrouppriv.h | 25 +++++++++++++++++++++++
+ src/util/vircgroupv1.c   | 44 +++++++++++++++++++++++++++-------------
+ src/util/vircgroupv2.c   | 44 +++++++++++++++++++++++++++-------------
+ tests/Makefile.am        |  1 +
+ 5 files changed, 97 insertions(+), 28 deletions(-)
+
+diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
+index a45c2e7f2f..10b934291c 100644
+--- a/src/util/vircgroup.c
++++ b/src/util/vircgroup.c
+@@ -1027,6 +1027,10 @@ virCgroupNewDetectMachine(const char *name,
+         }
+     }
+ 
++    (*group)->unitName = virSystemdGetMachineUnitByPID(pid);
++    if (virSystemdHasMachined() == 0 && !(*group)->unitName)
++        return -1;
++
+     return 0;
+ }
+ 
+@@ -1146,6 +1150,12 @@ virCgroupNewMachineSystemd(const char *name,
+         return -1;
+     }
+ 
++    (*group)->unitName = virSystemdGetMachineUnitByPID(pidleader);
++    if (!(*group)->unitName) {
++        virCgroupFree(group);
++        return -1;
++    }
++
+     if (virCgroupAddProcess(*group, pidleader) < 0) {
+         virErrorPtr saved;
+ 
+@@ -3553,6 +3563,7 @@ virCgroupFree(virCgroupPtr *group)
+ 
+     VIR_FREE((*group)->unified.mountPoint);
+     VIR_FREE((*group)->unified.placement);
++    VIR_FREE((*group)->unitName);
+ 
+     VIR_FREE((*group)->path);
+     VIR_FREE(*group);
+diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h
+index f2a80aeb82..b4a9e0b379 100644
+--- a/src/util/vircgrouppriv.h
++++ b/src/util/vircgrouppriv.h
+@@ -27,6 +27,7 @@
+ 
+ #include "vircgroup.h"
+ #include "vircgroupbackend.h"
++#include "virdbus.h"
+ 
+ struct _virCgroupV1Controller {
+     int type;
+@@ -66,8 +67,32 @@ struct _virCgroup {
+ 
+     virCgroupV1Controller legacy[VIR_CGROUP_CONTROLLER_LAST];
+     virCgroupV2Controller unified;
++
++    char *unitName;
+ };
+ 
++#define virCgroupSetValueDBus(unitName, key, ...) \
++    ({ \
++        int __ret = -1; \
++        do { \
++            DBusConnection *__conn; \
++            if (!(__conn = virDBusGetSystemBus())) \
++                break; \
++            __ret = virDBusCallMethod(__conn, NULL, NULL, \
++                                      "org.freedesktop.systemd1", \
++                                      "/org/freedesktop/systemd1", \
++                                      "org.freedesktop.systemd1.Manager", \
++                                      "SetUnitProperties", \
++                                      "sba(sv)", \
++                                      unitName, \
++                                      true, \
++                                      1, \
++                                      key, \
++                                      __VA_ARGS__); \
++        } while (0); \
++        __ret; \
++    })
++
+ int virCgroupSetValueRaw(const char *path,
+                          const char *value);
+ 
+diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c
+index c35088a3c4..7ec8f3a316 100644
+--- a/src/util/vircgroupv1.c
++++ b/src/util/vircgroupv1.c
+@@ -931,7 +931,6 @@ virCgroupV1SetBlkioWeight(virCgroupPtr group,
+                           unsigned int weight)
+ {
+     g_autofree char *path = NULL;
+-    g_autofree char *value = NULL;
+ 
+     if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
+                                     "blkio.bfq.weight", &path) < 0) {
+@@ -953,9 +952,14 @@ virCgroupV1SetBlkioWeight(virCgroupPtr group,
+         return -1;
+     }
+ 
+-    value = g_strdup_printf("%u", weight);
++    if (group->unitName) {
++        return virCgroupSetValueDBus(group->unitName, "BlockIOWeight",
++                                     "t", (unsigned long long) weight);
++    } else {
++        g_autofree char *value = g_strdup_printf("%u", weight);
+ 
+-    return virCgroupSetValueRaw(path, value);
++        return virCgroupSetValueRaw(path, value);
++    }
+ }
+ 
+ 
+@@ -1188,15 +1192,8 @@ virCgroupV1SetBlkioDeviceWeight(virCgroupPtr group,
+                                 const char *devPath,
+                                 unsigned int weight)
+ {
+-    g_autofree char *str = NULL;
+-    g_autofree char *blkstr = NULL;
+     g_autofree char *path = NULL;
+ 
+-    if (!(blkstr = virCgroupGetBlockDevString(devPath)))
+-        return -1;
+-
+-    str = g_strdup_printf("%s%d", blkstr, weight);
+-
+     if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
+                                     "blkio.weight_device", &path) < 0) {
+         return -1;
+@@ -1208,7 +1205,21 @@ virCgroupV1SetBlkioDeviceWeight(virCgroupPtr group,
+         return -1;
+     }
+ 
+-    return virCgroupSetValueRaw(path, str);
++    if (group->unitName) {
++        return virCgroupSetValueDBus(group->unitName, "BlockIODeviceWeight",
++                                     "a(st)",
++                                     1, path, (unsigned long long) weight);
++    } else {
++        g_autofree char *str = NULL;
++        g_autofree char *blkstr = NULL;
++
++        if (!(blkstr = virCgroupGetBlockDevString(devPath)))
++            return -1;
++
++        str = g_strdup_printf("%s%d", blkstr, weight);
++
++        return virCgroupSetValueRaw(path, str);
++    }
+ }
+ 
+ 
+@@ -1849,9 +1860,14 @@ static int
+ virCgroupV1SetCpuShares(virCgroupPtr group,
+                         unsigned long long shares)
+ {
+-    return virCgroupSetValueU64(group,
+-                                VIR_CGROUP_CONTROLLER_CPU,
+-                                "cpu.shares", shares);
++    if (group->unitName) {
++        return virCgroupSetValueDBus(group->unitName, "CPUShares",
++                                     "t", shares);
++    } else {
++        return virCgroupSetValueU64(group,
++                                    VIR_CGROUP_CONTROLLER_CPU,
++                                    "cpu.shares", shares);
++    }
+ }
+ 
+ 
+diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
+index 4682a6a920..8fe4894a9e 100644
+--- a/src/util/vircgroupv2.c
++++ b/src/util/vircgroupv2.c
+@@ -606,7 +606,6 @@ virCgroupV2SetBlkioWeight(virCgroupPtr group,
+                           unsigned int weight)
+ {
+     g_autofree char *path = NULL;
+-    g_autofree char *value = NULL;
+     const char *format = "%u";
+ 
+     if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
+@@ -630,9 +629,14 @@ virCgroupV2SetBlkioWeight(virCgroupPtr group,
+         return -1;
+     }
+ 
+-    value = g_strdup_printf(format, weight);
++    if (group->unitName) {
++        return virCgroupSetValueDBus(group->unitName, "IOWeight",
++                                     "t", (unsigned long long) weight);
++    } else {
++        g_autofree char *value = g_strdup_printf(format, weight);
+ 
+-    return virCgroupSetValueRaw(path, value);
++        return virCgroupSetValueRaw(path, value);
++    }
+ }
+ 
+ 
+@@ -817,13 +821,6 @@ virCgroupV2SetBlkioDeviceWeight(virCgroupPtr group,
+                                 unsigned int weight)
+ {
+     g_autofree char *path = NULL;
+-    g_autofree char *str = NULL;
+-    g_autofree char *blkstr = NULL;
+-
+-    if (!(blkstr = virCgroupGetBlockDevString(devPath)))
+-        return -1;
+-
+-    str = g_strdup_printf("%s%d", blkstr, weight);
+ 
+     if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
+                                     "io.weight", &path) < 0) {
+@@ -836,7 +833,21 @@ virCgroupV2SetBlkioDeviceWeight(virCgroupPtr group,
+         return -1;
+     }
+ 
+-    return virCgroupSetValueRaw(path, str);
++    if (group->unitName) {
++        return virCgroupSetValueDBus(group->unitName, "IODeviceWeight",
++                                     "a(st)",
++                                     1, path, (unsigned long long) weight);
++    } else {
++        g_autofree char *str = NULL;
++        g_autofree char *blkstr = NULL;
++
++        if (!(blkstr = virCgroupGetBlockDevString(devPath)))
++            return -1;
++
++        str = g_strdup_printf("%s%d", blkstr, weight);
++
++        return virCgroupSetValueRaw(path, str);
++    }
+ }
+ 
+ 
+@@ -1455,9 +1466,14 @@ static int
+ virCgroupV2SetCpuShares(virCgroupPtr group,
+                         unsigned long long shares)
+ {
+-    return virCgroupSetValueU64(group,
+-                                VIR_CGROUP_CONTROLLER_CPU,
+-                                "cpu.weight", shares);
++    if (group->unitName) {
++        return virCgroupSetValueDBus(group->unitName, "CPUWeight",
++                                     "t", shares);
++    } else {
++        return virCgroupSetValueU64(group,
++                                    VIR_CGROUP_CONTROLLER_CPU,
++                                    "cpu.weight", shares);
++    }
+ }
+ 
+ 
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index f957c7d1ba..b030d0e8f6 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -1188,6 +1188,7 @@ libvirportallocatormock_la_LIBADD = $(MOCKLIBS_LIBS)
+ 
+ vircgrouptest_SOURCES = \
+ 	vircgrouptest.c testutils.h testutils.c
++vircgrouptest_CFLAGS = $(DBUS_CFLAGS) $(AM_CFLAGS)
+ vircgrouptest_LDADD = $(LDADDS)
+ 
+ libvircgroupmock_la_SOURCES = \
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-vircgroupv1-refactor-virCgroupV1DetectPlacement.patch b/SOURCES/libvirt-vircgroupv1-refactor-virCgroupV1DetectPlacement.patch
new file mode 100644
index 0000000..d8035c1
--- /dev/null
+++ b/SOURCES/libvirt-vircgroupv1-refactor-virCgroupV1DetectPlacement.patch
@@ -0,0 +1,77 @@
+From a88996cc6c72a6f7fd034c0890747c54cc377484 Mon Sep 17 00:00:00 2001
+Message-Id: <a88996cc6c72a6f7fd034c0890747c54cc377484@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Fri, 19 Feb 2021 13:33:56 +0100
+Subject: [PATCH] vircgroupv1: refactor virCgroupV1DetectPlacement
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Remove one level of indentation by splitting the condition.
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 5f56dd7c83493f14a471bb9e33415b04329a08bf)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <ce477880853d3a9988389789611b68c458834600.1613737828.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/vircgroupv1.c | 39 ++++++++++++++++++++++-----------------
+ 1 file changed, 22 insertions(+), 17 deletions(-)
+
+diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c
+index 7ec8f3a316..09165ece4d 100644
+--- a/src/util/vircgroupv1.c
++++ b/src/util/vircgroupv1.c
+@@ -339,23 +339,28 @@ virCgroupV1DetectPlacement(virCgroupPtr group,
+     for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
+         const char *typestr = virCgroupV1ControllerTypeToString(i);
+ 
+-        if (virCgroupV1MountOptsMatchController(controllers, typestr) &&
+-            group->legacy[i].mountPoint != NULL &&
+-            group->legacy[i].placement == NULL) {
+-            /*
+-             * selfpath == "/" + path="" -> "/"
+-             * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service"
+-             * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo"
+-             */
+-            if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) {
+-                group->legacy[i].placement = g_strdup(selfpath);
+-            } else {
+-                bool delim = STREQ(selfpath, "/") || STREQ(path, "");
+-
+-                group->legacy[i].placement = g_strdup_printf("%s%s%s", selfpath,
+-                                                             delim ? "" : "/",
+-                                                             path);
+-            }
++        if (!virCgroupV1MountOptsMatchController(controllers, typestr))
++            continue;
++
++        if (!group->legacy[i].mountPoint)
++            continue;
++
++        if (group->legacy[i].placement)
++            continue;
++
++        /*
++         * selfpath == "/" + path="" -> "/"
++         * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service"
++         * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo"
++         */
++        if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) {
++            group->legacy[i].placement = g_strdup(selfpath);
++        } else {
++            bool delim = STREQ(selfpath, "/") || STREQ(path, "");
++
++            group->legacy[i].placement = g_strdup_printf("%s%s%s", selfpath,
++                                                         delim ? "" : "/",
++                                                         path);
+         }
+     }
+ 
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-vircgroupv1-use-defines-for-cpu-period-and-quota-limits.patch b/SOURCES/libvirt-vircgroupv1-use-defines-for-cpu-period-and-quota-limits.patch
new file mode 100644
index 0000000..649bb1e
--- /dev/null
+++ b/SOURCES/libvirt-vircgroupv1-use-defines-for-cpu-period-and-quota-limits.patch
@@ -0,0 +1,66 @@
+From 2fb78d18ea95c2dcb4c5b0e29171636e51bb2149 Mon Sep 17 00:00:00 2001
+Message-Id: <2fb78d18ea95c2dcb4c5b0e29171636e51bb2149@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Thu, 21 Jan 2021 10:24:04 -0300
+Subject: [PATCH] vircgroupv1: use defines for cpu period and quota limits
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit bc760f4d7c4f964fadcb2a73e126b0053e7a9b06)
+
+https://bugzilla.redhat.com/1915733
+
+Signed-off-by: Daniel Henrique Barboza <dbarboza@redhat.com>
+Message-Id: <20210121132406.337681-3-dbarboza@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+---
+ src/util/vircgroupv1.c | 23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c
+index d2ec7106db..c35088a3c4 100644
+--- a/src/util/vircgroupv1.c
++++ b/src/util/vircgroupv1.c
+@@ -1869,13 +1869,13 @@ static int
+ virCgroupV1SetCpuCfsPeriod(virCgroupPtr group,
+                            unsigned long long cfs_period)
+ {
+-    /* The cfs_period should be greater or equal than 1ms, and less or equal
+-     * than 1s.
+-     */
+-    if (cfs_period < 1000 || cfs_period > 1000000) {
++    if (cfs_period < VIR_CGROUP_CPU_PERIOD_MIN ||
++        cfs_period > VIR_CGROUP_CPU_PERIOD_MAX) {
+         virReportError(VIR_ERR_INVALID_ARG,
+-                       _("cfs_period '%llu' must be in range (1000, 1000000)"),
+-                       cfs_period);
++                       _("cfs_period '%llu' must be in range (%llu, %llu)"),
++                       cfs_period,
++                       VIR_CGROUP_CPU_PERIOD_MIN,
++                       VIR_CGROUP_CPU_PERIOD_MAX);
+         return -1;
+     }
+ 
+@@ -1899,13 +1899,14 @@ static int
+ virCgroupV1SetCpuCfsQuota(virCgroupPtr group,
+                           long long cfs_quota)
+ {
+-    /* The cfs_quota should be greater or equal than 1ms */
+     if (cfs_quota >= 0 &&
+-        (cfs_quota < 1000 ||
+-         cfs_quota > ULLONG_MAX / 1000)) {
++        (cfs_quota < VIR_CGROUP_CPU_QUOTA_MIN ||
++         cfs_quota > VIR_CGROUP_CPU_QUOTA_MAX)) {
+         virReportError(VIR_ERR_INVALID_ARG,
+-                       _("cfs_quota '%lld' must be in range (1000, %llu)"),
+-                       cfs_quota, ULLONG_MAX / 1000);
++                       _("cfs_quota '%lld' must be in range (%llu, %llu)"),
++                       cfs_quota,
++                       VIR_CGROUP_CPU_QUOTA_MIN,
++                       VIR_CGROUP_CPU_QUOTA_MAX);
+         return -1;
+     }
+ 
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-vircgroupv2-move-task-into-cgroup-before-enabling-controllers.patch b/SOURCES/libvirt-vircgroupv2-move-task-into-cgroup-before-enabling-controllers.patch
new file mode 100644
index 0000000..7a161d9
--- /dev/null
+++ b/SOURCES/libvirt-vircgroupv2-move-task-into-cgroup-before-enabling-controllers.patch
@@ -0,0 +1,155 @@
+From 41a7547b32786b1a84c8ee7bad0c4cf9559ea4b9 Mon Sep 17 00:00:00 2001
+Message-Id: <41a7547b32786b1a84c8ee7bad0c4cf9559ea4b9@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Fri, 19 Feb 2021 13:33:57 +0100
+Subject: [PATCH] vircgroupv2: move task into cgroup before enabling
+ controllers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When we create a new child cgroup and the parent cgroup has any process
+attached to it enabling controllers for the child cgroup fails with
+error. We need to move the process into the child cgroup first before
+enabling any controllers.
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 382fa15cde538cba3888a89b301fd3d9a0ce69ea)
+
+Conflicts:
+    src/util/vircgroup.c
+        - missing upstream g_autofree rewrite
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <85d34403caacb571cb78539d5c4f56eee9484d57.1613737828.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/vircgroup.c        | 13 +++++++------
+ src/util/vircgroupbackend.h |  1 +
+ src/util/vircgroupv1.c      |  1 +
+ src/util/vircgroupv2.c      | 13 +++++++++++++
+ 4 files changed, 22 insertions(+), 6 deletions(-)
+
+diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
+index 10b934291c..8f5bcd94f4 100644
+--- a/src/util/vircgroup.c
++++ b/src/util/vircgroup.c
+@@ -622,13 +622,14 @@ static int
+ virCgroupMakeGroup(virCgroupPtr parent,
+                    virCgroupPtr group,
+                    bool create,
++                   pid_t pid,
+                    unsigned int flags)
+ {
+     size_t i;
+ 
+     for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
+         if (group->backends[i] &&
+-            group->backends[i]->makeGroup(parent, group, create, flags) < 0) {
++            group->backends[i]->makeGroup(parent, group, create, pid, flags) < 0) {
+             virCgroupRemove(group);
+             return -1;
+         }
+@@ -857,8 +858,8 @@ virCgroupNewPartition(const char *path,
+         goto cleanup;
+ 
+     if (parent) {
+-        if (virCgroupMakeGroup(parent, *group, create, VIR_CGROUP_NONE) < 0)
+-            goto cleanup;
++        if (virCgroupMakeGroup(parent, *group, create, -1, VIR_CGROUP_NONE) < 0)
++            return -1;
+     }
+ 
+     ret = 0;
+@@ -924,7 +925,7 @@ virCgroupNewDomainPartition(virCgroupPtr partition,
+      * a group for driver, is to avoid overhead to track
+      * cumulative usage that we don't need.
+      */
+-    if (virCgroupMakeGroup(partition, *group, create,
++    if (virCgroupMakeGroup(partition, *group, create, -1,
+                            VIR_CGROUP_MEM_HIERACHY) < 0) {
+         virCgroupFree(group);
+         return -1;
+@@ -978,7 +979,7 @@ virCgroupNewThread(virCgroupPtr domain,
+     if (virCgroupNew(-1, name, domain, controllers, group) < 0)
+         return -1;
+ 
+-    if (virCgroupMakeGroup(domain, *group, create, VIR_CGROUP_THREAD) < 0) {
++    if (virCgroupMakeGroup(domain, *group, create, -1, VIR_CGROUP_THREAD) < 0) {
+         virCgroupFree(group);
+         return -1;
+     }
+@@ -1065,7 +1066,7 @@ virCgroupEnableMissingControllers(char *path,
+                          &tmp) < 0)
+             goto cleanup;
+ 
+-        if (virCgroupMakeGroup(parent, tmp, true, VIR_CGROUP_SYSTEMD) < 0) {
++        if (virCgroupMakeGroup(parent, tmp, true, -1, VIR_CGROUP_SYSTEMD) < 0) {
+             virCgroupFree(&tmp);
+             goto cleanup;
+         }
+diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h
+index e12a2e8b9d..ac7b3ae517 100644
+--- a/src/util/vircgroupbackend.h
++++ b/src/util/vircgroupbackend.h
+@@ -119,6 +119,7 @@ typedef int
+ (*virCgroupMakeGroupCB)(virCgroupPtr parent,
+                         virCgroupPtr group,
+                         bool create,
++                        pid_t pid,
+                         unsigned int flags);
+ 
+ typedef int
+diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c
+index 09165ece4d..eb2b611cee 100644
+--- a/src/util/vircgroupv1.c
++++ b/src/util/vircgroupv1.c
+@@ -601,6 +601,7 @@ static int
+ virCgroupV1MakeGroup(virCgroupPtr parent,
+                      virCgroupPtr group,
+                      bool create,
++                     pid_t pid G_GNUC_UNUSED,
+                      unsigned int flags)
+ {
+     size_t i;
+diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
+index 8fe4894a9e..5e19ed8332 100644
+--- a/src/util/vircgroupv2.c
++++ b/src/util/vircgroupv2.c
+@@ -398,10 +398,17 @@ virCgroupV2EnableController(virCgroupPtr group,
+ }
+ 
+ 
++static int
++virCgroupV2AddTask(virCgroupPtr group,
++                   pid_t pid,
++                   unsigned int flags);
++
++
+ static int
+ virCgroupV2MakeGroup(virCgroupPtr parent,
+                      virCgroupPtr group,
+                      bool create,
++                     pid_t pid,
+                      unsigned int flags)
+ {
+     g_autofree char *path = NULL;
+@@ -449,6 +456,12 @@ virCgroupV2MakeGroup(virCgroupPtr parent,
+             }
+         } else {
+             size_t i;
++
++            if (pid > 0) {
++                if (virCgroupV2AddTask(group, pid, VIR_CGROUP_TASK_PROCESS) < 0)
++                    return -1;
++            }
++
+             for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
+                 int rc;
+ 
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-vircgroupv2-properly-detect-placement-of-running-VM.patch b/SOURCES/libvirt-vircgroupv2-properly-detect-placement-of-running-VM.patch
new file mode 100644
index 0000000..799b56b
--- /dev/null
+++ b/SOURCES/libvirt-vircgroupv2-properly-detect-placement-of-running-VM.patch
@@ -0,0 +1,88 @@
+From 9cf56b5a0d1394fef10afdd763dc8005457bbaf5 Mon Sep 17 00:00:00 2001
+Message-Id: <9cf56b5a0d1394fef10afdd763dc8005457bbaf5@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Fri, 19 Feb 2021 13:33:51 +0100
+Subject: [PATCH] vircgroupv2: properly detect placement of running VM
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When libvirtd starts a VM it internally stores a path to the main
+cgroup. When we restart libvirtd we should get to the same state.
+
+When we start a VM on host with systemd the cgroup is created for us and
+the process is already placed into that cgroup and we detect the path
+created by systemd using /proc/$PID/cgroup. After that we create
+sub-cgroups and move all threads there.
+
+Once libvirtd is restarted we again detect the cgroup path using
+/proc/$PID/cgroup, but in this case we will get a different path because
+the main thread was moved to a "emulator" cgroup.
+
+Instead of ignoring the "emulator" directory when validating cgroups
+remove it completely when detecting cgroup otherwise cgroups will not
+work properly when libvirtd is restarted.
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 902c6644a8ec292789d561b3188e576c37a86872)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <10fb6b61cbb4f9caf8e8ba7706ec01d1da41fc67.1613737828.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/vircgroupv2.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
+index 92ae3ec839..4682a6a920 100644
+--- a/src/util/vircgroupv2.c
++++ b/src/util/vircgroupv2.c
+@@ -121,12 +121,6 @@ virCgroupV2ValidateMachineGroup(virCgroupPtr group,
+     if (!(tmp = strrchr(group->unified.placement, '/')))
+         return false;
+ 
+-    if (STREQ(tmp, "/emulator")) {
+-        *tmp = '\0';
+-
+-        if (!(tmp = strrchr(group->unified.placement, '/')))
+-            return false;
+-    }
+     tmp++;
+ 
+     if (STRNEQ(tmp, partmachinename) &&
+@@ -197,6 +191,9 @@ virCgroupV2DetectPlacement(virCgroupPtr group,
+                            const char *controllers,
+                            const char *selfpath)
+ {
++    g_autofree char *placement = g_strdup(selfpath);
++    char *tmp = NULL;
++
+     if (group->unified.placement)
+         return 0;
+ 
+@@ -207,12 +204,18 @@ virCgroupV2DetectPlacement(virCgroupPtr group,
+     if (STRNEQ(controllers, ""))
+         return 0;
+ 
++    /* Running VM will have the main thread placed in emulator cgroup
++     * but we need to get the main cgroup. */
++    tmp = g_strrstr(placement, "/emulator");
++    if (tmp)
++        *tmp = '\0';
++
+     /*
+      * selfpath == "/" + path="" -> "/"
+      * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service"
+      * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo"
+      */
+-    group->unified.placement = g_strdup_printf("%s%s%s", selfpath,
++    group->unified.placement = g_strdup_printf("%s%s%s", placement,
+                                                (STREQ(selfpath, "/") || STREQ(path, "") ? "" : "/"), path);
+ 
+     return 0;
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-vircgroupv2-use-defines-for-cpu-period-and-quota-limits.patch b/SOURCES/libvirt-vircgroupv2-use-defines-for-cpu-period-and-quota-limits.patch
new file mode 100644
index 0000000..bcb1769
--- /dev/null
+++ b/SOURCES/libvirt-vircgroupv2-use-defines-for-cpu-period-and-quota-limits.patch
@@ -0,0 +1,78 @@
+From b96501e90f7b3fbea1427ab6adeade7d8e707d07 Mon Sep 17 00:00:00 2001
+Message-Id: <b96501e90f7b3fbea1427ab6adeade7d8e707d07@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Thu, 21 Jan 2021 10:24:05 -0300
+Subject: [PATCH] vircgroupv2: use defines for cpu period and quota limits
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+(cherry picked from commit 98a09ca48ed4fc011abf2aa290e02ce1b8f1bb5f)
+
+https://bugzilla.redhat.com/1915733
+
+Signed-off-by: Daniel Henrique Barboza <dbarboza@redhat.com>
+Message-Id: <20210121132406.337681-4-dbarboza@redhat.com>
+Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
+---
+ src/util/vircgroupv2.c | 25 +++++++++++++------------
+ 1 file changed, 13 insertions(+), 12 deletions(-)
+
+diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
+index 1d8c599f6a..92ae3ec839 100644
+--- a/src/util/vircgroupv2.c
++++ b/src/util/vircgroupv2.c
+@@ -1476,12 +1476,12 @@ virCgroupV2SetCpuCfsPeriod(virCgroupPtr group,
+     g_autofree char *str = NULL;
+     char *tmp;
+ 
+-    /* The cfs_period should be greater or equal than 1ms, and less or equal
+-     * than 1s.
+-     */
+-    if (cfs_period < 1000 || cfs_period > 1000000) {
++    if (cfs_period < VIR_CGROUP_CPU_PERIOD_MIN ||
++        cfs_period > VIR_CGROUP_CPU_PERIOD_MAX) {
+         virReportError(VIR_ERR_INVALID_ARG,
+-                       _("cfs_period '%llu' must be in range (1000, 1000000)"),
++                       _("cfs_period '%llu' must be in range (%llu, %llu)"),
++                       VIR_CGROUP_CPU_PERIOD_MIN,
++                       VIR_CGROUP_CPU_PERIOD_MAX,
+                        cfs_period);
+         return -1;
+     }
+@@ -1537,17 +1537,18 @@ static int
+ virCgroupV2SetCpuCfsQuota(virCgroupPtr group,
+                           long long cfs_quota)
+ {
+-    /* The cfs_quota should be greater or equal than 1ms */
+     if (cfs_quota >= 0 &&
+-        (cfs_quota < 1000 ||
+-         cfs_quota > ULLONG_MAX / 1000)) {
++        (cfs_quota < VIR_CGROUP_CPU_QUOTA_MIN ||
++         cfs_quota > VIR_CGROUP_CPU_QUOTA_MAX)) {
+         virReportError(VIR_ERR_INVALID_ARG,
+-                       _("cfs_quota '%lld' must be in range (1000, %llu)"),
+-                       cfs_quota, ULLONG_MAX / 1000);
++                       _("cfs_quota '%lld' must be in range (%llu, %llu)"),
++                       cfs_quota,
++                       VIR_CGROUP_CPU_QUOTA_MIN,
++                       VIR_CGROUP_CPU_QUOTA_MAX);
+         return -1;
+     }
+ 
+-    if (cfs_quota == ULLONG_MAX / 1000) {
++    if (cfs_quota == VIR_CGROUP_CPU_QUOTA_MAX) {
+         return virCgroupSetValueStr(group,
+                                     VIR_CGROUP_CONTROLLER_CPU,
+                                     "cpu.max", "max");
+@@ -1572,7 +1573,7 @@ virCgroupV2GetCpuCfsQuota(virCgroupPtr group,
+     }
+ 
+     if (STREQLEN(str, "max", 3)) {
+-        *cfs_quota = ULLONG_MAX / 1000;
++        *cfs_quota = VIR_CGROUP_CPU_QUOTA_MAX;
+         return 0;
+     }
+ 
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-virhostcpu.c-fix-die_id-parsing-for-Power-hosts.patch b/SOURCES/libvirt-virhostcpu.c-fix-die_id-parsing-for-Power-hosts.patch
new file mode 100644
index 0000000..2257052
--- /dev/null
+++ b/SOURCES/libvirt-virhostcpu.c-fix-die_id-parsing-for-Power-hosts.patch
@@ -0,0 +1,94 @@
+From b5aa3a33bc770714f8a68954c05ea362fcfd4d47 Mon Sep 17 00:00:00 2001
+Message-Id: <b5aa3a33bc770714f8a68954c05ea362fcfd4d47@dist-git>
+From: Daniel Henrique Barboza <danielhb413@gmail.com>
+Date: Mon, 5 Oct 2020 10:25:30 -0400
+Subject: [PATCH] virhostcpu.c: fix 'die_id' parsing for Power hosts
+
+Commit 7b79ee2f78 makes assumptions about die_id parsing in
+the sysfs that aren't true for Power hosts. In both Power8
+and Power9, running 5.6 and 4.18 kernel respectively,
+'die_id' is set to -1:
+
+$ cat /sys/devices/system/cpu/cpu0/topology/die_id
+-1
+
+This breaks virHostCPUGetDie() parsing because it is trying to
+retrieve an unsigned integer, causing problems during VM start:
+
+virFileReadValueUint:4128 : internal error: Invalid unsigned integer
+value '-1' in file '/sys/devices/system/cpu/cpu0/topology/die_id'
+
+This isn't necessarily a PowerPC only behavior. Linux kernel commit
+0e344d8c70 added in the former Documentation/cputopology.txt, now
+Documentation/admin-guide/cputopology.rst, that:
+
+  To be consistent on all architectures, include/linux/topology.h
+  provides default definitions for any of the above macros that are
+  not defined by include/asm-XXX/topology.h:
+
+  1) topology_physical_package_id: -1
+  2) topology_die_id: -1
+  (...)
+
+This means that it might be expected that an architecture that
+does not implement the die_id element will mark it as -1 in
+sysfs.
+
+It is not required to change die_id implementation from uInt to
+Int because of that. Instead, let's change the parsing of the
+die_id in virHostCPUGetDie() to read an integer value and, in
+case it's -1, default it to zero like in case of file not found.
+This is enough to solve the issue Power hosts are experiencing.
+
+Fixes: 7b79ee2f78bbf2af76df2f6466919e19ae05aeeb
+Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 0137bf0dab2738d5443e2f407239856e2aa25bb3)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1876742
+
+Signed-off-by: Daniel Henrique Barboza <dbarboza@redhat.com>
+Message-Id: <20201005142530.3961036-1-dbarboza@redhat.com>
+Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
+---
+ src/util/virhostcpu.c | 21 ++++++++++++++-------
+ 1 file changed, 14 insertions(+), 7 deletions(-)
+
+diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
+index 09c959cd25..218272d7ec 100644
+--- a/src/util/virhostcpu.c
++++ b/src/util/virhostcpu.c
+@@ -221,16 +221,23 @@ virHostCPUGetSocket(unsigned int cpu, unsigned int *socket)
+ int
+ virHostCPUGetDie(unsigned int cpu, unsigned int *die)
+ {
+-    int ret = virFileReadValueUint(die,
+-                                   "%s/cpu/cpu%u/topology/die_id",
+-                                   SYSFS_SYSTEM_PATH, cpu);
++    int die_id;
++    int ret = virFileReadValueInt(&die_id,
++                                  "%s/cpu/cpu%u/topology/die_id",
++                                  SYSFS_SYSTEM_PATH, cpu);
+ 
+-    /* If the file is not there, it's 0 */
+-    if (ret == -2)
+-        *die = 0;
+-    else if (ret < 0)
++    if (ret == -1)
+         return -1;
+ 
++    /* If the file is not there, it's 0.
++     * Another alternative is die_id set to -1, meaning that
++     * the arch does not have die_id support. Set @die to
++     * 0 in this case too. */
++    if (ret == -2 || die_id < 0)
++        *die = 0;
++    else
++        *die = die_id;
++
+     return 0;
+ }
+ 
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-virsh-nodedev-ability-to-filter-CSS-capabilities.patch b/SOURCES/libvirt-virsh-nodedev-ability-to-filter-CSS-capabilities.patch
new file mode 100644
index 0000000..ec533f6
--- /dev/null
+++ b/SOURCES/libvirt-virsh-nodedev-ability-to-filter-CSS-capabilities.patch
@@ -0,0 +1,130 @@
+From 09ce043fb64e92147992898ccdfc9a6c31c6051e Mon Sep 17 00:00:00 2001
+Message-Id: <09ce043fb64e92147992898ccdfc9a6c31c6051e@dist-git>
+From: Boris Fiuczynski <fiuczy@linux.ibm.com>
+Date: Thu, 8 Oct 2020 11:06:58 -0400
+Subject: [PATCH] virsh: nodedev: ability to filter CSS capabilities
+
+Allow to filter for CSS devices.
+
+Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
+(cherry picked from commit ab655afa186a81ddfd247d2c187c160dd05740e5)
+https://bugzilla.redhat.com/show_bug.cgi?id=1853289
+https://bugzilla.redhat.com/show_bug.cgi?id=1865932
+Message-Id: <20201008150700.52157-4-bfiuczyn@redhat.com>
+Reviewed-by: Erik Skultety <eskultet@redhat.com>
+---
+ docs/formatnode.html.in           | 12 ++++++++++++
+ docs/manpages/virsh.rst           |  2 +-
+ include/libvirt/libvirt-nodedev.h |  1 +
+ src/conf/node_device_conf.h       |  3 ++-
+ src/conf/virnodedeviceobj.c       |  3 ++-
+ src/libvirt-nodedev.c             |  1 +
+ tools/virsh-nodedev.c             |  2 ++
+ 7 files changed, 21 insertions(+), 3 deletions(-)
+
+diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in
+index c2a8f8fb7a..0e9658fd29 100644
+--- a/docs/formatnode.html.in
++++ b/docs/formatnode.html.in
+@@ -341,6 +341,18 @@
+               <dd>The device number.</dd>
+             </dl>
+           </dd>
++          <dt><code>css</code></dt>
++          <dd>Describes a Channel SubSystem (CSS) device commonly found on
++          the S390 architecture. Sub-elements include:
++            <dl>
++              <dt><code>cssid</code></dt>
++              <dd>The channel subsystem identifier.</dd>
++              <dt><code>ssid</code></dt>
++              <dd>The subchannel-set identifier.</dd>
++              <dt><code>devno</code></dt>
++              <dd>The device number.</dd>
++            </dl>
++          </dd>
+         </dl>
+       </dd>
+     </dl>
+diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst
+index c637caa583..0804465d44 100644
+--- a/docs/manpages/virsh.rst
++++ b/docs/manpages/virsh.rst
+@@ -4886,7 +4886,7 @@ List all of the devices available on the node that are known by libvirt.
+ separated by comma, e.g. --cap pci,scsi. Valid capability types include
+ 'system', 'pci', 'usb_device', 'usb', 'net', 'scsi_host', 'scsi_target',
+ 'scsi', 'storage', 'fc_host', 'vports', 'scsi_generic', 'drm', 'mdev',
+-'mdev_types', 'ccw'.
++'mdev_types', 'ccw', 'css'.
+ If *--tree* is used, the output is formatted in a tree representing parents of each
+ node.  *cap* and *--tree* are mutually exclusive.
+ 
+diff --git a/include/libvirt/libvirt-nodedev.h b/include/libvirt/libvirt-nodedev.h
+index a2ad61ac6d..dd2ffd5782 100644
+--- a/include/libvirt/libvirt-nodedev.h
++++ b/include/libvirt/libvirt-nodedev.h
+@@ -81,6 +81,7 @@ typedef enum {
+     VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES    = 1 << 13, /* Capable of mediated devices */
+     VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV          = 1 << 14, /* Mediated device */
+     VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV       = 1 << 15, /* CCW device */
++    VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV       = 1 << 16, /* CSS device */
+ } virConnectListAllNodeDeviceFlags;
+ 
+ int                     virConnectListAllNodeDevices (virConnectPtr conn,
+diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
+index 19ea3fc7c2..6fe51ed04c 100644
+--- a/src/conf/node_device_conf.h
++++ b/src/conf/node_device_conf.h
+@@ -364,7 +364,8 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps);
+                  VIR_CONNECT_LIST_NODE_DEVICES_CAP_DRM           | \
+                  VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES    | \
+                  VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV          | \
+-                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV)
++                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV       | \
++                 VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV)
+ 
+ int
+ virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHostPtr scsi_host);
+diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c
+index 8c8ffd6d24..a27a84355a 100644
+--- a/src/conf/virnodedeviceobj.c
++++ b/src/conf/virnodedeviceobj.c
+@@ -827,7 +827,8 @@ virNodeDeviceObjMatch(virNodeDeviceObjPtr obj,
+               MATCH(DRM)           ||
+               MATCH(MDEV_TYPES)    ||
+               MATCH(MDEV)          ||
+-              MATCH(CCW_DEV)))
++              MATCH(CCW_DEV)       ||
++              MATCH(CSS_DEV)))
+             return false;
+     }
+ 
+diff --git a/src/libvirt-nodedev.c b/src/libvirt-nodedev.c
+index dce46b7181..71d81f6278 100644
+--- a/src/libvirt-nodedev.c
++++ b/src/libvirt-nodedev.c
+@@ -101,6 +101,7 @@ virNodeNumOfDevices(virConnectPtr conn, const char *cap, unsigned int flags)
+  *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES
+  *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV
+  *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV
++ *   VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV
+  *
+  * Returns the number of node devices found or -1 and sets @devices to NULL in
+  * case of error.  On success, the array stored into @devices is guaranteed to
+diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c
+index 26b3acc608..f4e402c35d 100644
+--- a/tools/virsh-nodedev.c
++++ b/tools/virsh-nodedev.c
+@@ -462,6 +462,8 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED)
+             flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV;
+             break;
+         case VIR_NODE_DEV_CAP_CSS_DEV:
++            flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV;
++            break;
+         case VIR_NODE_DEV_CAP_LAST:
+             break;
+         }
+-- 
+2.28.0
+
diff --git a/SOURCES/libvirt-virsystemd-export-virSystemdHasMachined.patch b/SOURCES/libvirt-virsystemd-export-virSystemdHasMachined.patch
new file mode 100644
index 0000000..df82c03
--- /dev/null
+++ b/SOURCES/libvirt-virsystemd-export-virSystemdHasMachined.patch
@@ -0,0 +1,65 @@
+From c8fb30409d501e5d9299ac7c08c43917b199a72b Mon Sep 17 00:00:00 2001
+Message-Id: <c8fb30409d501e5d9299ac7c08c43917b199a72b@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Fri, 19 Feb 2021 13:33:52 +0100
+Subject: [PATCH] virsystemd: export virSystemdHasMachined
+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: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit a51147d9065217d9087449b4e601e3294c0a22cf)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <9a861adc0dc51679d7178e464255c80465247333.1613737828.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/libvirt_private.syms | 1 +
+ src/util/virsystemd.c    | 2 +-
+ src/util/virsystemd.h    | 2 ++
+ 3 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index 9d87e2a27b..a869d1f7a4 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -3243,6 +3243,7 @@ virSystemdGetActivation;
+ virSystemdGetMachineNameByPID;
+ virSystemdHasLogind;
+ virSystemdHasLogindResetCachedValue;
++virSystemdHasMachined;
+ virSystemdHasMachinedResetCachedValue;
+ virSystemdMakeScopeName;
+ virSystemdMakeSliceName;
+diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
+index 96d43e5440..ca708cd1bd 100644
+--- a/src/util/virsystemd.c
++++ b/src/util/virsystemd.c
+@@ -153,7 +153,7 @@ void virSystemdHasLogindResetCachedValue(void)
+  * -1 = error
+  *  0 = machine1 is available
+  */
+-static int
++int
+ virSystemdHasMachined(void)
+ {
+     int ret;
+diff --git a/src/util/virsystemd.h b/src/util/virsystemd.h
+index dfea75948b..9ce16b7de1 100644
+--- a/src/util/virsystemd.h
++++ b/src/util/virsystemd.h
+@@ -57,6 +57,8 @@ int virSystemdTerminateMachine(const char *name);
+ 
+ void virSystemdNotifyStartup(void);
+ 
++int virSystemdHasMachined(void);
++
+ int virSystemdHasLogind(void);
+ 
+ int virSystemdCanSuspend(bool *result);
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-virsystemd-introduce-virSystemdGetMachineByPID.patch b/SOURCES/libvirt-virsystemd-introduce-virSystemdGetMachineByPID.patch
new file mode 100644
index 0000000..c7242c1
--- /dev/null
+++ b/SOURCES/libvirt-virsystemd-introduce-virSystemdGetMachineByPID.patch
@@ -0,0 +1,102 @@
+From a3a5c16f04d044502eecedbef6043bce79043df9 Mon Sep 17 00:00:00 2001
+Message-Id: <a3a5c16f04d044502eecedbef6043bce79043df9@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Fri, 19 Feb 2021 13:33:53 +0100
+Subject: [PATCH] virsystemd: introduce virSystemdGetMachineByPID
+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: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit 385704d5a4e1c02c21fb5779fa5067cf0d8ab56c)
+
+Conflicts:
+    src/util/virsystemd.c
+        - missing upstream glib dbus rewrite
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <7de7eae45f139e79c45731263924ae078f3e33c5.1613737828.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/util/virsystemd.c | 46 +++++++++++++++++++++++++++++++++----------
+ 1 file changed, 36 insertions(+), 10 deletions(-)
+
+diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
+index ca708cd1bd..394eb13f38 100644
+--- a/src/util/virsystemd.c
++++ b/src/util/virsystemd.c
+@@ -200,19 +200,24 @@ virSystemdHasLogind(void)
+ }
+ 
+ 
+-char *
+-virSystemdGetMachineNameByPID(pid_t pid)
++/**
++ * virSystemdGetMachineByPID:
++ * @conn: dbus connection
++ * @pid: pid of running VM
++ *
++ * Returns dbus object path to VM registered with machined.
++ * On error returns NULL.
++ */
++static char *
++virSystemdGetMachineByPID(DBusConnection *conn,
++                          pid_t pid)
+ {
+-    DBusConnection *conn;
+     DBusMessage *reply = NULL;
+-    char *name = NULL, *object = NULL;
++    char *object = NULL;
+ 
+     if (virSystemdHasMachined() < 0)
+         goto cleanup;
+ 
+-    if (!(conn = virDBusGetSystemBus()))
+-        goto cleanup;
+-
+     if (virDBusCallMethod(conn, &reply, NULL,
+                           "org.freedesktop.machine1",
+                           "/org/freedesktop/machine1",
+@@ -224,12 +229,33 @@ virSystemdGetMachineNameByPID(pid_t pid)
+     if (virDBusMessageDecode(reply, "o", &object) < 0)
+         goto cleanup;
+ 
+-    virDBusMessageUnref(reply);
+-    reply = NULL;
+-
+     VIR_DEBUG("Domain with pid %lld has object path '%s'",
+               (long long) pid, object);
+ 
++ cleanup:
++    virDBusMessageUnref(reply);
++
++    return object;
++}
++
++
++char *
++virSystemdGetMachineNameByPID(pid_t pid)
++{
++    DBusConnection *conn;
++    DBusMessage *reply = NULL;
++    char *name = NULL, *object = NULL;
++
++    if (virSystemdHasMachined() < 0)
++        goto cleanup;
++
++    if (!(conn = virDBusGetSystemBus()))
++        goto cleanup;
++
++    object = virSystemdGetMachineByPID(conn, pid);
++    if (!object)
++        goto cleanup;
++
+     if (virDBusCallMethod(conn, &reply, NULL,
+                           "org.freedesktop.machine1",
+                           object,
+-- 
+2.30.0
+
diff --git a/SOURCES/libvirt-virsystemd-introduce-virSystemdGetMachineUnitByPID.patch b/SOURCES/libvirt-virsystemd-introduce-virSystemdGetMachineUnitByPID.patch
new file mode 100644
index 0000000..5918571
--- /dev/null
+++ b/SOURCES/libvirt-virsystemd-introduce-virSystemdGetMachineUnitByPID.patch
@@ -0,0 +1,205 @@
+From 9ec1193393c48198fd05b795bcce0d607b45d4ee Mon Sep 17 00:00:00 2001
+Message-Id: <9ec1193393c48198fd05b795bcce0d607b45d4ee@dist-git>
+From: Pavel Hrdina <phrdina@redhat.com>
+Date: Fri, 19 Feb 2021 13:33:54 +0100
+Subject: [PATCH] virsystemd: introduce virSystemdGetMachineUnitByPID
+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: Michal Privoznik <mprivozn@redhat.com>
+(cherry picked from commit d3fb774b1ed548c0338b3338a87094dafea32aa2)
+
+Conflicts:
+    src/util/virsystemd.c
+    tests/virsystemdtest.c
+        - missing upstream glib dbus rewrite
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
+
+Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
+Message-Id: <28be8d962cde455d215fe9ee09fbdcc4145e931f.1613737828.git.phrdina@redhat.com>
+Reviewed-by: Ján Tomko <jtomko@redhat.com>
+---
+ src/libvirt_private.syms |  1 +
+ src/util/virsystemd.c    | 48 ++++++++++++++++++++++++++++++++
+ src/util/virsystemd.h    |  2 ++
+ tests/virsystemdtest.c   | 59 ++++++++++++++++++++++++++++++++++------
+ 4 files changed, 101 insertions(+), 9 deletions(-)
+
+diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
+index a869d1f7a4..af6f32fb1e 100644
+--- a/src/libvirt_private.syms
++++ b/src/libvirt_private.syms
+@@ -3241,6 +3241,7 @@ virSystemdCanSuspend;
+ virSystemdCreateMachine;
+ virSystemdGetActivation;
+ virSystemdGetMachineNameByPID;
++virSystemdGetMachineUnitByPID;
+ virSystemdHasLogind;
+ virSystemdHasLogindResetCachedValue;
+ virSystemdHasMachined;
+diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
+index 394eb13f38..0b8e21ae46 100644
+--- a/src/util/virsystemd.c
++++ b/src/util/virsystemd.c
+@@ -280,6 +280,54 @@ virSystemdGetMachineNameByPID(pid_t pid)
+ }
+ 
+ 
++/**
++ * virSystemdGetMachineUnitByPID:
++ * @pid: pid of running VM
++ *
++ * Returns systemd Unit name of a running VM registered with machined.
++ * On error returns NULL.
++ */
++char *
++virSystemdGetMachineUnitByPID(pid_t pid)
++{
++    DBusConnection *conn;
++    DBusMessage *reply = NULL;
++    char *unit = NULL, *object = NULL;
++
++    if (virSystemdHasMachined() < 0)
++        goto cleanup;
++
++    if (!(conn = virDBusGetSystemBus()))
++        goto cleanup;
++
++    object = virSystemdGetMachineByPID(conn, pid);
++    if (!object)
++        goto cleanup;
++
++    if (virDBusCallMethod(conn, &reply, NULL,
++                          "org.freedesktop.machine1",
++                          object,
++                          "org.freedesktop.DBus.Properties",
++                          "Get",
++                          "ss",
++                          "org.freedesktop.machine1.Machine",
++                          "Unit") < 0)
++        goto cleanup;
++
++    if (virDBusMessageDecode(reply, "v", "s", &unit) < 0)
++        goto cleanup;
++
++    VIR_DEBUG("Domain with pid %lld has unit name '%s'",
++              (long long) pid, unit);
++
++ cleanup:
++    VIR_FREE(object);
++    virDBusMessageUnref(reply);
++
++    return unit;
++}
++
++
+ /**
+  * virSystemdCreateMachine:
+  * @name: driver unique name of the machine
+diff --git a/src/util/virsystemd.h b/src/util/virsystemd.h
+index 9ce16b7de1..cd329c49f9 100644
+--- a/src/util/virsystemd.h
++++ b/src/util/virsystemd.h
+@@ -69,6 +69,8 @@ int virSystemdCanHybridSleep(bool *result);
+ 
+ char *virSystemdGetMachineNameByPID(pid_t pid);
+ 
++char *virSystemdGetMachineUnitByPID(pid_t pid);
++
+ int virSystemdGetActivation(virSystemdActivationMap *map,
+                             size_t nmap,
+                             virSystemdActivationPtr *act);
+diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c
+index eb510b40e4..475bf8debc 100644
+--- a/tests/virsystemdtest.c
++++ b/tests/virsystemdtest.c
+@@ -69,19 +69,42 @@ VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block,
+                                                     &object_path))
+                     goto error;
+             } else if (STREQ(member, "Get")) {
+-                const char *name = "qemu-demo";
++                const char *name = NULL;
++                char *iface = NULL;
++                char *prop = NULL;
+                 DBusMessageIter iter;
+                 DBusMessageIter sub;
+ 
+-                dbus_message_iter_init_append(reply, &iter);
+-                dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+-                                                 "s", &sub);
+-
+-                if (!dbus_message_iter_append_basic(&sub,
+-                                                    DBUS_TYPE_STRING,
+-                                                    &name))
++                if (virDBusMessageDecode(message, "ss", &iface, &prop) < 0)
+                     goto error;
+-                dbus_message_iter_close_container(&iter, &sub);
++
++                VIR_FREE(iface);
++
++                if (STREQ(prop, "Name")) {
++                    name = "qemu-demo";
++                } else if (STREQ(prop, "Unit")) {
++                    name = "machine-qemu-demo.scope";
++                } else {
++                    dbus_set_error_const(error,
++                                         "org.freedesktop.systemd.badthing",
++                                         "Unknown machine property");
++                }
++
++                VIR_FREE(prop);
++
++                if (name) {
++                    dbus_message_iter_init_append(reply, &iter);
++
++                    dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
++                                                     "s", &sub);
++
++                    if (!dbus_message_iter_append_basic(&sub,
++                                                        DBUS_TYPE_STRING,
++                                                        &name))
++                        goto error;
++
++                    dbus_message_iter_close_container(&iter, &sub);
++                }
+             }
+         }
+     } else if (STREQ(service, "org.freedesktop.login1")) {
+@@ -376,6 +399,23 @@ testGetMachineName(const void *opaque G_GNUC_UNUSED)
+ }
+ 
+ 
++static int
++testGetMachineUnit(const void *opaque G_GNUC_UNUSED)
++{
++    g_autofree char *tmp = virSystemdGetMachineUnitByPID(1234);
++
++    if (!tmp) {
++        fprintf(stderr, "%s", "Failed to create get machine unit\n");
++        return -1;
++    }
++
++    if (STREQ(tmp, "machine-qemu-demo.scope"))
++        return 0;
++
++    return -1;
++}
++
++
+ struct testNameData {
+     const char *name;
+     const char *expected;
+@@ -698,6 +738,7 @@ mymain(void)
+     DO_TEST("Test create bad systemd ", testCreateBadSystemd);
+     DO_TEST("Test create with network ", testCreateNetwork);
+     DO_TEST("Test getting machine name ", testGetMachineName);
++    DO_TEST("Test getting machine unit ", testGetMachineUnit);
+ 
+ # define TEST_SCOPE(_name, unitname, _legacy) \
+     do { \
+-- 
+2.30.0
+
diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec
index a5bc743..e3acab3 100644
--- a/SPECS/libvirt.spec
+++ b/SPECS/libvirt.spec
@@ -219,7 +219,7 @@
 Summary: Library providing a simple virtualization API
 Name: libvirt
 Version: 6.0.0
-Release: 28.1%{?dist}%{?extra_release}
+Release: 35%{?dist}%{?extra_release}
 License: LGPLv2+
 URL: https://libvirt.org/
 
@@ -669,7 +669,91 @@ Patch437: libvirt-virDevMapperGetTargets-Don-t-ignore-EBADF.patch
 Patch438: libvirt-virdevmapper-Don-t-cache-device-mapper-major.patch
 Patch439: libvirt-virdevmapper-Handle-kernel-without-device-mapper-support.patch
 Patch440: libvirt-virdevmapper-Ignore-all-errors-when-opening-dev-mapper-control.patch
-Patch441: libvirt-qemu-Add-virtio-related-options-to-vsock.patch
+Patch441: libvirt-qemu-substitute-missing-model-name-for-host-passthrough.patch
+Patch442: libvirt-rpc-gendispatch-handle-empty-flags.patch
+Patch443: libvirt-rpc-add-support-for-filtering-acls-by-uint-params.patch
+Patch444: libvirt-rpc-require-write-acl-for-guest-agent-in-virDomainInterfaceAddresses.patch
+Patch445: libvirt-qemu-agent-set-ifname-to-NULL-after-freeing.patch
+Patch446: libvirt-qemu-Fix-domfsinfo-for-non-PCI-device-information-from-guest-agent.patch
+Patch447: libvirt-virDomainNetFindIdx-add-support-for-CCW-addresses.patch
+Patch448: libvirt-check-for-NULL-before-calling-g_regex_unref.patch
+Patch449: libvirt-virhostcpu.c-fix-die_id-parsing-for-Power-hosts.patch
+Patch450: libvirt-qemuFirmwareFillDomain-Fill-NVRAM-template-on-migration-too.patch
+Patch451: libvirt-node_device-refactor-udevProcessCCW.patch
+Patch452: libvirt-node_device-detect-CSS-devices.patch
+Patch453: libvirt-virsh-nodedev-ability-to-filter-CSS-capabilities.patch
+Patch454: libvirt-node_device-detect-DASD-devices.patch
+Patch455: libvirt-udevProcessCSS-Check-if-def-driver-is-non-NULL.patch
+Patch456: libvirt-cpu_map-Add-missing-x86-features-in-0x7-CPUID-leaf.patch
+Patch457: libvirt-cpu_map-Add-missing-x86-features-in-0x80000008-CPUID-leaf.patch
+Patch458: libvirt-cpu_map-Add-missing-AMD-SVM-features.patch
+Patch459: libvirt-Add-testdata-for-AMD-EPYC-7502.patch
+Patch460: libvirt-cpu_map-Defined-and-enable-EPYC-Rome-model.patch
+Patch461: libvirt-cpu_map-Remove-monitor-feature-from-EPYC-Rome.patch
+Patch462: libvirt-tests-qemuxml2argv-Use-existing-machine-type-for-numatune-distances-case.patch
+Patch463: libvirt-qemuxml2xmltest-Add-numatune-distance-test-case.patch
+Patch464: libvirt-conf-Move-and-rename-virDomainParseScaledValue.patch
+Patch465: libvirt-numa_conf-Drop-CPU-from-name-of-two-functions.patch
+Patch466: libvirt-qemu_command-Rename-qemuBuildNumaArgStr.patch
+Patch467: libvirt-qemuBuildMachineCommandLine-Drop-needless-check.patch
+Patch468: libvirt-numa_conf-Make-virDomainNumaSetNodeCpumask-return-void.patch
+Patch469: libvirt-Allow-NUMA-nodes-without-vCPUs.patch
+Patch470: libvirt-conf-Parse-and-format-HMAT.patch
+Patch471: libvirt-conf-Validate-NUMA-HMAT-configuration.patch
+Patch472: libvirt-numa-expose-HMAT-APIs.patch
+Patch473: libvirt-qemu-Introduce-QEMU_CAPS_NUMA_HMAT-capability.patch
+Patch474: libvirt-qemu-Build-HMAT-command-line.patch
+Patch475: libvirt-qemuBuildNumaCommandLine-Fix-masterInitiator-check.patch
+Patch476: libvirt-numa_conf-Properly-check-for-caches-in-virDomainNumaDefValidate.patch
+Patch477: libvirt-RNG-Allow-interleaving-of-domain-cpu-numa-cell-children.patch
+Patch478: libvirt-conf-properly-clear-out-autogenerated-macvtap-names-when-formatting-parsing.patch
+Patch479: libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch
+Patch480: libvirt-util-replace-macvtap-name-reservation-bitmap-with-a-simple-counter.patch
+Patch481: libvirt-util-assign-tap-device-names-using-a-monotonically-increasing-integer.patch
+Patch482: libvirt-util-virNetDevTapCreate-initialize-fd-to-1.patch
+Patch483: libvirt-cpu_map-Fix-Icelake-Server-model-number.patch
+Patch484: libvirt-cputestdata-Add-test-data-for-Snowridge.patch
+Patch485: libvirt-cpu_map-Add-support-for-fsrm-CPU-feature.patch
+Patch486: libvirt-cpu_map-Add-support-for-core-capability-CPU-feature.patch
+Patch487: libvirt-cpu_map-Add-support-for-split-lock-detect-CPU-feature.patch
+Patch488: libvirt-cpu_map-Define-and-enable-Snowridge-model.patch
+Patch489: libvirt-util-fix-typo-in-VIR_MOCK_WRAP_RET_ARGS.patch
+Patch490: libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-in-unit-tests.patch
+Patch491: libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-by-default.patch
+Patch492: libvirt-tests-fix-iptables-test-case-commandline-options-in-virfirewalltest.c.patch
+Patch493: libvirt-network-be-more-verbose-about-the-reason-for-a-firewall-reload.patch
+Patch494: libvirt-util-always-check-for-ebtables-iptables-binaries-even-when-using-firewalld.patch
+Patch495: libvirt-util-synchronize-with-firewalld-before-we-start-calling-iptables-directly.patch
+Patch496: libvirt-util-call-iptables-directly-rather-than-via-firewalld.patch
+Patch497: libvirt-util-virhostcpu-Fail-when-fetching-CPU-Stats-for-invalid-cpu.patch
+Patch498: libvirt-qemu-move-cgroup-cpu-period-and-quota-defines-to-vircgroup.h.patch
+Patch499: libvirt-vircgroupv1-use-defines-for-cpu-period-and-quota-limits.patch
+Patch500: libvirt-vircgroupv2-use-defines-for-cpu-period-and-quota-limits.patch
+Patch501: libvirt-vircgroup-fix-cpu-quota-maximum-limit.patch
+Patch502: libvirt-util-add-virNetDevGetPhysPortName.patch
+Patch503: libvirt-util-avoid-manual-VIR_FREE-of-a-g_autofree-pointer-in-virPCIGetName.patch
+Patch504: libvirt-util-Add-phys_port_name-support-on-virPCIGetNetName.patch
+Patch505: libvirt-vircgroupv2-properly-detect-placement-of-running-VM.patch
+Patch506: libvirt-virsystemd-export-virSystemdHasMachined.patch
+Patch507: libvirt-virsystemd-introduce-virSystemdGetMachineByPID.patch
+Patch508: libvirt-virsystemd-introduce-virSystemdGetMachineUnitByPID.patch
+Patch509: libvirt-vircgroup-use-DBus-call-to-systemd-for-some-APIs.patch
+Patch510: libvirt-vircgroupv1-refactor-virCgroupV1DetectPlacement.patch
+Patch511: libvirt-vircgroupv2-move-task-into-cgroup-before-enabling-controllers.patch
+Patch512: libvirt-vircgroup-introduce-virCgroupV1Exists-and-virCgroupV2Exists.patch
+Patch513: libvirt-vircgroup-introduce-nested-cgroup-to-properly-work-with-systemd.patch
+Patch514: libvirt-tests-add-cgroup-nested-tests.patch
+Patch515: libvirt-vircgroup-correctly-free-nested-virCgroupPtr.patch
+Patch516: libvirt-qemu-Add-virtio-related-options-to-vsock.patch
+Patch517: libvirt-domain_validate-use-defines-for-cpu-period-and-quota-limits.patch
+Patch518: libvirt-docs-use-proper-cpu-quota-value-in-our-documentation.patch
+Patch519: libvirt-vircgroup-enforce-range-limit-for-cpu.shares.patch
+Patch520: libvirt-cgroup-use-virCgroupSetCpuShares-instead-of-virCgroupSetupCpuShares.patch
+Patch521: libvirt-cpumap-Add-support-for-ibrs-CPU-feature.patch
+Patch522: libvirt-cpumap-Add-support-for-svme-addr-check-CPU-feature.patch
+Patch523: libvirt-cpu_map-Add-EPYC-Milan-x86-CPU-model.patch
+Patch524: libvirt-cpu_map-Install-x86_EPYC-Milan.xml.patch
+Patch525: libvirt-cpu_map-Fix-spelling-of-svme-addr-chk-feature.patch
 
 Requires: libvirt-daemon = %{version}-%{release}
 Requires: libvirt-daemon-config-network = %{version}-%{release}
@@ -2446,8 +2530,104 @@ exit 0
 
 
 %changelog
-* Tue Mar 23 2021 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-28.1.el8
-- qemu: Add virtio related options to vsock (rhbz#1941820)
+* Thu Mar  4 2021 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-35
+- vircgroupv2: properly detect placement of running VM (rhbz#1798463)
+- virsystemd: export virSystemdHasMachined (rhbz#1798463)
+- virsystemd: introduce virSystemdGetMachineByPID (rhbz#1798463)
+- virsystemd: introduce virSystemdGetMachineUnitByPID (rhbz#1798463)
+- vircgroup: use DBus call to systemd for some APIs (rhbz#1798463)
+- vircgroupv1: refactor virCgroupV1DetectPlacement (rhbz#1798463)
+- vircgroupv2: move task into cgroup before enabling controllers (rhbz#1798463)
+- vircgroup: introduce virCgroupV1Exists and virCgroupV2Exists (rhbz#1798463)
+- vircgroup: introduce nested cgroup to properly work with systemd (rhbz#1798463)
+- tests: add cgroup nested tests (rhbz#1798463)
+- vircgroup: correctly free nested virCgroupPtr (rhbz#1798463)
+- qemu: Add virtio related options to vsock (rhbz#1931548)
+- domain_validate: use defines for cpu period and quota limits (rhbz#1798463)
+- docs: use proper cpu quota value in our documentation (rhbz#1798463)
+- vircgroup: enforce range limit for cpu.shares (rhbz#1798463)
+- cgroup: use virCgroupSetCpuShares instead of virCgroupSetupCpuShares (rhbz#1798463)
+- cpumap: Add support for ibrs CPU feature (rhbz#1926864)
+- cpumap: Add support for svme-addr-check CPU feature (rhbz#1926864)
+- cpu_map: Add EPYC-Milan x86 CPU model (rhbz#1926864)
+- cpu_map: Install x86_EPYC-Milan.xml (rhbz#1926864)
+- cpu_map: Fix spelling of svme-addr-chk feature (rhbz#1926864)
+
+* Mon Feb  1 2021 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-34
+- qemu: move cgroup cpu period and quota defines to vircgroup.h (rhbz#1915733)
+- vircgroupv1: use defines for cpu period and quota limits (rhbz#1915733)
+- vircgroupv2: use defines for cpu period and quota limits (rhbz#1915733)
+- vircgroup: fix cpu quota maximum limit (rhbz#1915733)
+- util: add virNetDevGetPhysPortName (rhbz#1918708)
+- util: avoid manual VIR_FREE of a g_autofree pointer in virPCIGetName() (rhbz#1918708)
+- util: Add phys_port_name support on virPCIGetNetName (rhbz#1918708)
+
+* Thu Jan 21 2021 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-33
+- cpu_map: Fix Icelake Server model number (rhbz#1537734)
+- cputestdata: Add test data for Snowridge (rhbz#1537734)
+- cpu_map: Add support for fsrm CPU feature (rhbz#1537734)
+- cpu_map: Add support for core-capability CPU feature (rhbz#1537734)
+- cpu_map: Add support for split-lock-detect CPU feature (rhbz#1537734)
+- cpu_map: Define and enable Snowridge model (rhbz#1537734)
+- util: fix typo in VIR_MOCK_WRAP_RET_ARGS() (rhbz#1607929)
+- util/tests: enable locking on iptables/ebtables commandlines in unit tests (rhbz#1607929)
+- util/tests: enable locking on iptables/ebtables commandlines by default (rhbz#1607929)
+- tests: fix iptables test case commandline options in virfirewalltest.c (rhbz#1607929)
+- network: be more verbose about the reason for a firewall reload (rhbz#1607929)
+- util: always check for ebtables/iptables binaries, even when using firewalld (rhbz#1607929)
+- util: synchronize with firewalld before we start calling iptables directly (rhbz#1607929)
+- util: call iptables directly rather than via firewalld (rhbz#1607929)
+- util: virhostcpu: Fail when fetching CPU Stats for invalid cpu (rhbz#1915183)
+
+* Tue Dec 15 2020 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-32
+- util: replace macvtap name reservation bitmap with a simple counter (rhbz#1874304)
+- util: assign tap device names using a monotonically increasing integer (rhbz#1874304)
+- util: virNetDevTapCreate: initialize fd to -1 (rhbz#1874304)
+
+* Thu Dec 10 2020 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-31
+- conf: properly clear out autogenerated macvtap names when formatting/parsing (rhbz#1872610)
+- qemu: format 'ramfb' attribute for mediated devices (rhbz#1876297)
+
+* Mon Nov  9 2020 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-30
+- cpu_map: Add missing x86 features in 0x7 CPUID leaf (rhbz#1861506)
+- cpu_map: Add missing x86 features in 0x80000008 CPUID leaf (rhbz#1861506)
+- cpu_map: Add missing AMD SVM features (rhbz#1861506)
+- Add testdata for AMD EPYC 7502 (rhbz#1861506)
+- cpu_map: Defined and enable EPYC-Rome model (rhbz#1861506)
+- cpu_map: Remove monitor feature from EPYC-Rome (rhbz#1861506)
+- tests: qemuxml2argv: Use existing machine type for 'numatune-distances' case (rhbz#1749518)
+- qemuxml2xmltest: Add "numatune-distance" test case (rhbz#1749518)
+- conf: Move and rename virDomainParseScaledValue() (rhbz#1749518)
+- numa_conf: Drop CPU from name of two functions (rhbz#1749518)
+- qemu_command: Rename qemuBuildNumaArgStr() (rhbz#1749518)
+- qemuBuildMachineCommandLine: Drop needless check (rhbz#1749518)
+- numa_conf: Make virDomainNumaSetNodeCpumask() return void (rhbz#1749518)
+- Allow NUMA nodes without vCPUs (rhbz#1749518)
+- conf: Parse and format HMAT (rhbz#1749518)
+- conf: Validate NUMA HMAT configuration (rhbz#1749518)
+- numa: expose HMAT APIs (rhbz#1749518)
+- qemu: Introduce QEMU_CAPS_NUMA_HMAT capability (rhbz#1749518)
+- qemu: Build HMAT command line (rhbz#1749518)
+- qemuBuildNumaCommandLine: Fix @masterInitiator check (rhbz#1749518)
+- numa_conf: Properly check for caches in virDomainNumaDefValidate() (rhbz#1749518)
+- RNG: Allow interleaving of /domain/cpu/numa/cell children (rhbz#1749518)
+
+* Fri Oct  9 2020 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-29
+- qemu: substitute missing model name for host-passthrough (rhbz#1850680)
+- rpc: gendispatch: handle empty flags (CVE-2020-25637)
+- rpc: add support for filtering @acls by uint params (CVE-2020-25637)
+- rpc: require write acl for guest agent in virDomainInterfaceAddresses (CVE-2020-25637)
+- qemu: agent: set ifname to NULL after freeing (CVE-2020-25637)
+- qemu: Fix domfsinfo for non-PCI device information from guest agent (rhbz#1858771)
+- virDomainNetFindIdx: add support for CCW addresses (rhbz#1837495)
+- check for NULL before calling g_regex_unref (rhbz#1861176)
+- virhostcpu.c: fix 'die_id' parsing for Power hosts (rhbz#1876742)
+- qemuFirmwareFillDomain: Fill NVRAM template on migration too (rhbz#1880418)
+- node_device: refactor udevProcessCCW (rhbz#1853289, rhbz#1865932)
+- node_device: detect CSS devices (rhbz#1853289, rhbz#1865932)
+- virsh: nodedev: ability to filter CSS capabilities (rhbz#1853289, rhbz#1865932)
+- node_device: detect DASD devices (rhbz#1853289, rhbz#1865932)
+- udevProcessCSS: Check if def->driver is non-NULL (rhbz#1853289, rhbz#1865932)
 
 * Wed Aug 26 2020 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-28
 - virdevmapper: Don't cache device-mapper major (rhbz#1860421)