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:
+From: Markus Schade
+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
+Reviewed-by: Jiri Denemark
+(cherry picked from commit e06590f1708a599286f3ee3690b3dc50ee525d40)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1861506
+
+Signed-off-by: Jiri Denemark
+Message-Id: <2efe44ce5c929916c92656803d39635ae7c189b9.1602172344.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ 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 @@
++
++
++
++
++
++
++
++
++
+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 @@
++
++
++
++
++
++
++
++
++
++
++
+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 @@
++
++ EPYC-IBPB
++ AMD
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+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 @@
++
++ x86_64
++ EPYC-IBPB
++ AMD
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+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 @@
++
++ EPYC-IBPB
++ AMD
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+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 @@
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+--
+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
+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
+Reviewed-by: Daniel Henrique Barboza
+(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
+Message-Id: <365508c75e579e9037ad555d6c372068ccd50c95.1604938867.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ 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 @@
+ cpus
specifies the CPU or range of CPUs that are
+ part of the node. memory
specifies the node memory
+ in kibibytes (i.e. blocks of 1024 bytes).
++ Since 6.6.0 the cpus
attribute
++ is optional and if omitted a CPU-less NUMA node is created.
+ Since 1.2.11 one can use an additional unit
attribute to
+ define units in which memory
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 @@
+
+
+
+-
+-
+-
++
++
++
++
++
+
+
+
+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, "\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, "\n");
+ }
+-
+- VIR_FREE(cpustr);
+ }
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, " | \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 @@
++
++ QEMUGuest
++ c7a5fdb2-cdaf-9455-926a-d65c16db1809
++ 12582912
++ 12582912
++ 12
++
++ hvm
++
++
++
++
++
++
++
++
++
++ |
++ |
++ |
++ |
++ |
++ |
++
++
++
++ destroy
++ restart
++ restart
++
++ /usr/bin/qemu-system-x86_64
++
++
++
++
++
++
++
++
++
++
++
+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:
+From: Michal Privoznik
+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 | element can have two types of children
+elements: and (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
+Reviewed-by: Ján Tomko
+(cherry picked from commit fd2ad818b29ca56904dd228f0774f553f99c1157)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik
+Message-Id: <48b8e99ea6fbc6bcab0f7b3d17e7824ef1b232e2.1604938847.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ 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 @@
+
+
+
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
++
++
++
++
++
++
++
++
++
++
++
++
+
+
+
+--
+2.29.2
+
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?=
+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
+Fixes: 71efb59a4de7c51b1bc889a316f1796ebf55738f
+https://bugzilla.redhat.com/show_bug.cgi?id=1876907
+Reviewed-by: Peter Krempa
+Reviewed-by: Martin Kletzander
+(cherry picked from commit 92b252456ee6d6ffc6e39e62ce1ce6c50113e00e)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1861176
+
+Signed-off-by: Ján Tomko
+Message-Id: <7d3c84f6556d0d46ada037d5e56c831babba609f.1601639064.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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
+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
+Reviewed-by: Daniel Henrique Barboza
+(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
+Message-Id: <26a847deef5941fd90f892cf5fe1443cf3fc90ca.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ 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
+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
+ as under NUMA | and or
+ under numa/latencies.
+
+1: https://www.redhat.com/archives/libvir-list/2020-January/msg00422.html
+
+Signed-off-by: Michal Privoznik
+Reviewed-by: Daniel Henrique Barboza
+(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
+Message-Id:
+Reviewed-by: Ján Tomko
+---
+ 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.
+
+
++
++
++
++...
++<cpu>
++ ...
++ <numa>
++ <cell id='0' cpus='0-3' memory='512000' unit='KiB' discard='yes'/>
++ <cell id='1' cpus='4-7' memory='512000' unit='KiB' memAccess='shared'/>
++ <cell id='3' 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>
++ <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>
++...
++
++
++ Since 6.6.0 the cell
element can
++ have a cache
child element which describes memory side cache
++ for memory proximity domains. The cache
element has a
++ level
attribute describing the cache level and thus the
++ element can be repeated multiple times to describe different levels of
++ the cache.
++
++
++
++ The cache
element then has following mandatory attributes:
++
++
++
++ level
++
++ Level of the cache this description refers to.
++
++
++ associativity
++
++ Describes cache associativity (accepted values are none
,
++ direct
and full
).
++
++
++ policy
++
++ Describes cache write associativity (accepted values are
++ none
, writeback
and
++ writethrough
).
++
++
++
++
++ The cache
element has two mandatory child elements then:
++ size
and line
which describe cache size and
++ cache line size. Both elements accept two attributes: value
++ and unit
which set the value of corresponding cache
++ attribute.
++
++
++
++ The NUMA description has an optional interconnects
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).
++
++
++
++ The interconnects
element can have zero or more
++ latency
child elements to describe latency between two
++ memory nodes and zero or more bandwidth
child elements to
++ describe bandwidth between two memory nodes. Both these have the
++ following mandatory attributes:
++
++
++
++ initiator
++ Refers to the source NUMA node
++
++ target
++ Refers to the target NUMA node
++
++ type
++ The type of the access. Accepted values: access
,
++ read
, write
++
++ value
++ The actual value. For latency this is delay in nanoseconds, for
++ bandwidth this value is in kibibytes per second. Use additional
++ unit
attribute to change the units.
++
++
++
++ To describe latency from one NUMA node to a cache of another NUMA node
++ the latency
element has optional cache
++ attribute which in combination with target
attribute creates
++ full reference to distant NUMA node's cache level. For instance,
++ target='0' cache='1'
refers to the first level cache of NUMA
++ node 0.
++
++
+
+
+
+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 @@
+
+
+
+-
+-
+-
++
++
++
++
++
++
++
++
+
+
+
+@@ -148,6 +153,9 @@
+
+
+
++
++
++
+
+
+
+@@ -162,6 +170,102 @@
+
+
+
++
++
++
++
++
++
++
++ none
++ direct
++ full
++
++
++
++
++ none
++ writeback
++ writethrough
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++ access
++ read
++ write
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++ access
++ read
++ write
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+
+
+
+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, "\n");
+- virBufferAdjustIndent(buf, 2);
+- for (j = 0; j < ndistances; j++) {
+- if (distances[j].value) {
+- virBufferAddLit(buf, " \n");
++
++ if (ndistances) {
++ virDomainNumaDistancePtr distances = def->mem_nodes[i].distances;
++
++ virBufferAddLit(buf, "\n");
++ virBufferAdjustIndent(buf, 2);
++ for (j = 0; j < ndistances; j++) {
++ if (distances[j].value) {
++ virBufferAddLit(buf, " \n");
++ }
+ }
++ virBufferAdjustIndent(buf, -2);
++ virBufferAddLit(buf, " \n");
++ }
++
++ for (j = 0; j < ncaches; j++) {
++ virDomainNumaCachePtr cache = &def->mem_nodes[i].caches[j];
++
++ virBufferAsprintf(buf, "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,
++ " \n",
++ cache->size);
++
++ if (cache->line) {
++ virBufferAsprintf(buf,
++ " \n",
++ cache->line);
++ }
++
++ virBufferAdjustIndent(buf, -2);
++ virBufferAddLit(buf, " \n");
+ }
+- virBufferAdjustIndent(buf, -2);
+- virBufferAddLit(buf, " \n");
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "\n");
+ }
+ }
++
++ if (def->ninterconnects) {
++ virBufferAddLit(buf, "\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, "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, " \n");
++ }
++
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "\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 @@
++
++ QEMUGuest
++ c7a5fdb2-cdaf-9455-926a-d65c16db1809
++ 8388608
++ 8388608
++ 12
++
++ hvm
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++ |
++ |
++ |
++ |
++ |
++ |
++
++
++
++
++
++
++
++
++ destroy
++ restart
++ restart
++
++ /usr/bin/qemu-system-x86_64
++
++
++
++
++
++
++
++
++
++
++
+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
+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
+Reviewed-by: Daniel Henrique Barboza
+(cherry picked from commit f0611fe8830543d03d1871422f8c542453f0c8db)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik
+Message-Id:
+Reviewed-by: Ján Tomko
+---
+ 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:
+From: Laine Stump
+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
+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 - autogenerated
+names were not cleared for (which could
+also result in a macvtap device).
+
+Although the names of "vnetX" tap devices had always been
+automatically cleared when parsing (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),
+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
+Reviewed-by: Daniel Henrique Barboza
+(cherry picked from commit 282d135ddbb7203565cd5527b451469b14953994)
+
+https://bugzilla.redhat.com/1872610
+
+Signed-off-by: Laine Stump
+Message-Id: <20201202030100.458879-1-laine@redhat.com>
+Reviewed-by: Michal Privoznik
+---
+ 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-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
+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
+Reviewed-by: Daniel P. Berrangé
+(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
+Message-Id:
+Reviewed-by: Ján Tomko
+---
+ 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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+
+
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
++
+
+
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
++
+
+
+
+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 @@
+
+
+
++
++
+
+
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
++
+
+
+
+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 @@
+
+
+
++
++
++
+
+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 @@
+
+
+
++
++
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
++
++
+
+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 @@
+
+
+
++
++
++
+
+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 @@
+
+
+
++
+
+
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
++
+
+
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
++
++
++
+
+
+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 @@
+
+
+
++
++
++
++
+
+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 @@
+
+
+
++
++
+
+
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
+
+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 @@
+
+
+
++
++
+
+
+
+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 @@
+
+
+
++
+
+
+
+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 @@
+
+
+
++
+
+
+
+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 @@
+
+
+
++
+
+
+
+@@ -57,6 +58,7 @@
+
+
+
++
+
+
+ qemu64
+diff --git a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml
+index 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 @@
+
+
+
++
+
+
+
+@@ -57,6 +58,7 @@
+
+
+
++
+
+
+ qemu64
+diff --git a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml
+index 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 @@
+
+
+
++
+
+
+
+@@ -57,6 +58,7 @@
+
+
+
++
+
+
+ qemu64
+diff --git a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml
+index 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 @@
+
+
+
++
+
+
+
+@@ -56,6 +57,7 @@
+
+
+
++
+
+
+ qemu64
+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:
+From: Jiri Denemark
+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
+Reviewed-by: Daniel P. Berrangé
+(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
+Message-Id: <04da640b0fbbbcec9be63e552a3029f983bf879a.1602172344.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ 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 @@
+
+
+
++
++
++
+
+
+
+@@ -310,9 +313,18 @@
+
+
+
++
++
++
+
+
+
++
++
++
++
++
++
+
+
+
+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 @@
+
+
+
+-
++
+
+
+
+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 @@
+
+
+
++
+
+
+
+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 @@
+
+
+
++
+
+
+
+--
+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
+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
+Reviewed-by: Daniel P. Berrangé
+(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
+Message-Id: <27effeb5e12252982411796bd72e078d3afe49cb.1602172344.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ 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 @@
+
+
+
++
++
++
+
+
+
+
+
+
++
++
++
+
+
+
+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 @@
+
+
+
+-
++
+
+
+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 @@
+
+
+
++
+
+
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+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 @@
+
+
+
++
+
+--
+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
+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
+Reviewed-by: Jiri Denemark
+(cherry picked from commit e06dd56032acf904da1aedfc097fa0cae7cb0b0f)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1537734
+
+Signed-off-by: Tim Wiederhake
+Message-Id: <20210115141722.14986-5-twiederh@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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 @@
+
+
+
++
++
++
+
+
+
+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 @@
+
+
+
+-
++
+
+
+
+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 @@
+
+
+
++
+
+
+
+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 @@
+
+
+
++
+
+
+
+--
+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
+Date: Fri, 15 Jan 2021 15:17:19 +0100
+Subject: [PATCH] cpu_map: Add support for fsrm CPU feature
+
+Signed-off-by: Tim Wiederhake
+Reviewed-by: Jiri Denemark
+(cherry picked from commit 8c5c660b99101544d8cfcb8edbe48688c04bee25)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1537734
+
+Signed-off-by: Tim Wiederhake
+Message-Id: <20210115141722.14986-4-twiederh@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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 @@
+
+
+
++
++
++
+
+
+
+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 @@
+
+
+
+-
++
+
+
+
+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 @@
+
+
+
++
+
+
+
+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 @@
+
+
+
++
+
+
+
+--
+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
+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
+Reviewed-by: Jiri Denemark
+(cherry picked from commit 13db542cf3099f7955438e208dbe4b2b4e58067e)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1537734
+
+Signed-off-by: Tim Wiederhake
+Message-Id: <20210115141722.14986-6-twiederh@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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 @@
+
+
+
++
++
++
++
++
+
+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 @@
+
+
+
++
+
+
+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 @@
+
+
+
++
+
+
+
+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 @@
+
+
+
++
+
+--
+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:
+From: Tim Wiederhake
+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
+Reviewed-by: Jiri Denemark
+(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
+Message-Id: <20210115141722.14986-7-twiederh@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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 @@
+
+
+
++
+
+
+
+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 @@
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+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 @@
+
+- IvyBridge-IBRS
++ Snowridge
+ Intel
+
+
+@@ -16,36 +16,17 @@
+
+
+
+-
+
+-
+
+
+-
+-
+-
+-
+
+-
+-
+
+-
+
+-
+-
+-
+
+
+-
+-
+-
+-
+-
+-
+
+
+
+-
+
+
+
+@@ -53,7 +34,8 @@
+
+
+
+-
+-
+-
++
++
++
++
+
+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 @@
+
+- IvyBridge-IBRS
++ Snowridge
+ Intel
+
+
+
+-
+
+-
+
+-
+-
+-
+-
+-
+-
+-
+
+-
+-
+-
+
+
+-
+-
+-
+-
+-
+
+-
+
+
+
+@@ -36,6 +18,8 @@
+
+
+
+-
+-
++
++
++
++
+
+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 @@
+ athlon
+ Westmere-IBRS
+ Westmere
++ Snowridge
+ Skylake-Server-IBRS
+ Skylake-Server
+ Skylake-Client-IBRS
+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 @@
+ athlon
+ Westmere-IBRS
+ Westmere
++ Snowridge
+ Skylake-Server-IBRS
+ Skylake-Server
+ Skylake-Client-IBRS
+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 @@
+ athlon
+ Westmere-IBRS
+ Westmere
++ Snowridge
+ Skylake-Server-IBRS
+ Skylake-Server
+ Skylake-Client-IBRS
+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 @@
+ athlon
+ Westmere-IBRS
+ Westmere
++ Snowridge
+ Skylake-Server-noTSX-IBRS
+ Skylake-Server-IBRS
+ Skylake-Server
+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 @@
+ athlon
+ Westmere-IBRS
+ Westmere
++ Snowridge
+ Skylake-Server-noTSX-IBRS
+ Skylake-Server-IBRS
+ Skylake-Server
+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 @@
+ athlon
+ Westmere-IBRS
+ Westmere
++ Snowridge
+ Skylake-Server-noTSX-IBRS
+ Skylake-Server-IBRS
+ Skylake-Server
+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 @@
+ athlon
+ Westmere-IBRS
+ Westmere
++ Snowridge
+ Skylake-Server-noTSX-IBRS
+ Skylake-Server-IBRS
+ Skylake-Server
+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 @@
+ athlon
+ Westmere-IBRS
+ Westmere
++ Snowridge
+ Skylake-Server-noTSX-IBRS
+ Skylake-Server-IBRS
+ Skylake-Server
+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 @@
+ athlon
+ Westmere-IBRS
+ Westmere
++ Snowridge
+ Skylake-Server-noTSX-IBRS
+ Skylake-Server-IBRS
+ Skylake-Server
+--
+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:
+From: Markus Schade
+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
+Reviewed-by: Jiri Denemark
+(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
+Message-Id:
+Reviewed-by: Ján Tomko
+---
+ 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 @@
+
+
+
++
+
+
+
+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 @@
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+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 @@
+
+- EPYC-IBPB
++ EPYC-Rome
+ AMD
+
+
+
+-
+-
+-
+
+
+
+@@ -17,18 +14,11 @@
+
+
+
+-
+
+
+-
+-
+-
+-
+
+-
+
+
+-
+
+
+
+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 @@
+
+ x86_64
+- EPYC-IBPB
++ EPYC-Rome
+ AMD
+
+
+
+-
+-
+-
+
+
+
+@@ -18,18 +15,11 @@
+
+
+
+-
+
+
+-
+-
+-
+-
+
+-
+
+
+-
+
+
+
+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 @@
+
+- EPYC-IBPB
++ EPYC-Rome
+ AMD
+
+
+
+
+-
+-
+-
+
+
+
+
+
+
+-
+-
+-
+-
+-
+
+
+-
+-
+
+
+
+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 @@
+ Haswell-noTSX
+ Haswell-IBRS
+ Haswell
++ EPYC-Rome
+ EPYC-IBPB
+ EPYC
+ Dhyana
+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 @@
+ Haswell-noTSX
+ Haswell-IBRS
+ Haswell
++ EPYC-Rome
+ EPYC-IBPB
+ EPYC
+ Dhyana
+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 @@
+ Haswell-noTSX
+ Haswell-IBRS
+ Haswell
++ EPYC-Rome
+ EPYC-IBPB
+ EPYC
+ Dhyana
+--
+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:
+From: Tim Wiederhake
+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
+Reviewed-by: Jiri Denemark
+(cherry picked from commit 1278ac6265589cd83cc2e661056c860e98105507)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1537734
+
+Signed-off-by: Tim Wiederhake
+Message-Id: <20210115141722.14986-2-twiederh@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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 @@
+
+
+
+-
++
+
+
+
+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 @@
+
+
+
+-
++
+
+
+
+--
+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:
+From: Jiri Denemark
+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
+Reviewed-by: Peter Krempa
+(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
+Message-Id: <74b9257f49925312b025a99dd934a9613ca295d4.1602172344.git.jdenemar@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ 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 @@
+
+
+
+-
+
+
+
+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 @@
+ EPYC-Rome
+ AMD
+
++
+
+
+
+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 @@
+ EPYC-Rome
+ AMD
+
++
+
+
+
+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 @@
+
+
+
+-
+
+--
+2.29.2
+
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
+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
+Reviewed-by: Jiri Denemark
+(cherry picked from commit 59a585fdb047669ee36251c7338bb2e2ccd58998)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1537734
+
+Signed-off-by: Tim Wiederhake
+Message-Id: <20210115141722.14986-3-twiederh@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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 @@
++
++
++
++
++
++
++
++
+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 @@
++
++
++
++
++
++
++
++
++
++
+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 @@
++
++ IvyBridge-IBRS
++ Intel
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+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 @@
++
++ x86_64
++ Westmere-IBRS
++ Intel
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+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 @@
++
++ IvyBridge-IBRS
++ Intel
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+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 @@
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+--
+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
+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
+Reviewed-by: Daniel Henrique Barboza
+(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
+Message-Id: <20210116035151.1066734-6-laine@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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
+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
+Reviewed-by: Bjoern Walk
+Signed-off-by: Boris Fiuczynski
+(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
+---
+ 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 @@
+
+
+
++
+
+
+
+@@ -651,6 +652,21 @@
+
+
+
++
++
++ css
++
++
++
++
++
++
++
++
++
++
++
++
+
+
+
+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, "0x%x \n",
+ data->ccw_dev.cssid);
+ virBufferAsprintf(&buf, "0x%x \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 @@
+
+ ccw_0_0_10000
+- /sys/devices/css0/0.0.0000/0.0.10000
+- computer
++ /sys/devices/css0/0.0.0070/0.0.10000
++ css_0_0_0070
+
+ 0x0
+ 0x0
+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 @@
+
+ ccw_0_0_ffff
+- /sys/devices/css0/0.0.0000/0.0.ffff
+- computer
++ /sys/devices/css0/0.0.0070/0.0.ffff
++ css_0_0_0070
+
+ 0x0
+ 0x0
+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 @@
++
++ css_0_0_ffff
++ /sys/devices/css0/0.0.ffff
++ computer
++
++ 0x0
++ 0x0
++ 0xffff
++
++
+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:
+From: Boris Fiuczynski
+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
+Reviewed-by: Erik Skultety
+Signed-off-by: Boris Fiuczynski
+(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
+---
+ 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:
+From: Boris Fiuczynski
+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
+Reviewed-by: Bjoern Walk
+Signed-off-by: Boris Fiuczynski
+(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
+---
+ 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:
+From: Michal Privoznik
+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
+Reviewed-by: Daniel Henrique Barboza
+(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
+Message-Id:
+Reviewed-by: Ján Tomko
+---
+ 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:
+From: Michal Privoznik
+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
+ . There is nothing CPU specific about them. Drop the
+infix.
+
+Signed-off-by: Michal Privoznik
+Reviewed-by: Daniel Henrique Barboza
+(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
+Message-Id:
+Reviewed-by: Ján Tomko
+---
+ 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:
+From: Michal Privoznik
+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
+Reviewed-by: Daniel Henrique Barboza
+(cherry picked from commit 1050c6beb1f2238cd847d93eab17d658720b08e1)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik
+Message-Id: <8564849f4fc4aaca69eec3d2b7e59d03234ea39f.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ 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
+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
+with @cache attribute refer to an existing cache level. For
+instance:
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+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:
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+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
+Reviewed-by: Laine Stump
+(cherry picked from commit e41ac71fca309b50e2c8e6ec142d8fe1280ca2ad)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik
+Message-Id: <4bb47f9e97ca097cee1259449da4739b55753751.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ 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-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:
+From: Michal Privoznik
+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
+Reviewed-by: Daniel Henrique Barboza
+(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
+Message-Id: <0e8dfded8022b564ec7d0563cd745a0d3ffc815f.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ 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:
+From: Thomas Huth
+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é
+Signed-off-by: Thomas Huth
+(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
+---
+ 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:
+From: Michal Privoznik
+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
+Reviewed-by: Daniel Henrique Barboza
+(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
+Message-Id:
+Reviewed-by: Ján Tomko
+---
+ 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 @@
+
+
+
++
+ 4002050
+ 0
+ 61700241
+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 @@
+
+
+
++
+ 4002091
+ 0
+ 43100241
+--
+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?=
+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
+Reported-by: Ilja Van Sprundel
+Fixes: 0977b8aa071de550e1a013d35e2c72615e65d520
+Reviewed-by: Mauro Matteo Cascella
+(cherry picked from commit a63b48c5ecef077bf0f909a85f453a605600cf05)
+Signed-off-by: Ján Tomko
+
+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
+---
+ 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-block-Remove-active-write-bitmap-even-if-there-are-no-bitmaps-to-merge.patch b/SOURCES/libvirt-qemu-block-Remove-active-write-bitmap-even-if-there-are-no-bitmaps-to-merge.patch
new file mode 100644
index 0000000..78fb8d3
--- /dev/null
+++ b/SOURCES/libvirt-qemu-block-Remove-active-write-bitmap-even-if-there-are-no-bitmaps-to-merge.patch
@@ -0,0 +1,105 @@
+From cb297cdd8dc75abc8fd0d60dddf54cbe305d4c14 Mon Sep 17 00:00:00 2001
+Message-Id:
+From: Peter Krempa
+Date: Tue, 21 Jul 2020 13:56:23 +0200
+Subject: [PATCH] qemu: block: Remove 'active-write' bitmap even if there are
+ no bitmaps to merge
+
+The 'libvirt-tmp-activewrite' bitmap is added during the 'pivot'
+operation of block copy and active layer block commit operations
+regardless of whether there are any bitmaps to merge, but was not
+removed unless a bitmap was merged. This meant that subsequent attempts
+to merge into the same image would fail.
+
+Fix it by checking whether the 'libvirt-tmp-activewrite' would be used
+by the code and don't skip the code which would delete it.
+
+This is a regression introduced when we switched to the new code for
+block commit in <20a7abc2d2d> and for block copy in <7bfff40fdfe5>. The
+actual bug originates from <4fa8654ece>.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1857735
+
+Signed-off-by: Peter Krempa
+Reviewed-by: Eric Blake
+(cherry picked from commit 9d039863e2cae227cc73b7a886b40be5e5218a12)
+
+rhel-8.3: https://bugzilla.redhat.com/show_bug.cgi?id=1857779
+rhel-av-8.2.1: not cloned yet
+Message-Id: <4fea6a40be534d5a6fe7aad88d6bee1c3e77dcfb.1595332476.git.pkrempa@redhat.com>
+
+Reviewed-by: Jiri Denemark
+---
+ src/qemu/qemu_block.c | 3 ++-
+ tests/qemublocktestdata/bitmapblockcommit/empty | 9 +++++++++
+ .../bitmapblockcopy/empty-deep-out.json | 9 +++++++++
+ .../bitmapblockcopy/empty-shallow-out.json | 9 +++++++++
+ 4 files changed, 29 insertions(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
+index 18c3861a2e..dc5fa3da03 100644
+--- a/src/qemu/qemu_block.c
++++ b/src/qemu/qemu_block.c
+@@ -2935,7 +2935,7 @@ qemuBlockGetBitmapMergeActions(virStorageSourcePtr topsrc,
+
+ if (!(bitmaps = qemuBlockGetBitmapMergeActionsGetBitmaps(topsrc, bitmapname,
+ blockNamedNodeData)))
+- return 0;
++ goto done;
+
+ for (next = bitmaps; next; next = next->next) {
+ const char *curbitmap = next->data;
+@@ -2992,6 +2992,7 @@ qemuBlockGetBitmapMergeActions(virStorageSourcePtr topsrc,
+ return -1;
+ }
+
++ done:
+ if (writebitmapsrc &&
+ qemuMonitorTransactionBitmapRemove(act, writebitmapsrc->nodeformat,
+ "libvirt-tmp-activewrite") < 0)
+diff --git a/tests/qemublocktestdata/bitmapblockcommit/empty b/tests/qemublocktestdata/bitmapblockcommit/empty
+index 9260011852..eddef0ddcd 100644
+--- a/tests/qemublocktestdata/bitmapblockcommit/empty
++++ b/tests/qemublocktestdata/bitmapblockcommit/empty
+@@ -1 +1,10 @@
+ merge bitmpas:
++[
++ {
++ "type": "block-dirty-bitmap-remove",
++ "data": {
++ "node": "libvirt-2-format",
++ "name": "libvirt-tmp-activewrite"
++ }
++ }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcopy/empty-deep-out.json b/tests/qemublocktestdata/bitmapblockcopy/empty-deep-out.json
+index e69de29bb2..99f2589ed4 100644
+--- a/tests/qemublocktestdata/bitmapblockcopy/empty-deep-out.json
++++ b/tests/qemublocktestdata/bitmapblockcopy/empty-deep-out.json
+@@ -0,0 +1,9 @@
++[
++ {
++ "type": "block-dirty-bitmap-remove",
++ "data": {
++ "node": "mirror-format-node",
++ "name": "libvirt-tmp-activewrite"
++ }
++ }
++]
+diff --git a/tests/qemublocktestdata/bitmapblockcopy/empty-shallow-out.json b/tests/qemublocktestdata/bitmapblockcopy/empty-shallow-out.json
+index e69de29bb2..99f2589ed4 100644
+--- a/tests/qemublocktestdata/bitmapblockcopy/empty-shallow-out.json
++++ b/tests/qemublocktestdata/bitmapblockcopy/empty-shallow-out.json
+@@ -0,0 +1,9 @@
++[
++ {
++ "type": "block-dirty-bitmap-remove",
++ "data": {
++ "node": "mirror-format-node",
++ "name": "libvirt-tmp-activewrite"
++ }
++ }
++]
+--
+2.27.0
+
diff --git a/SOURCES/libvirt-qemu-blockjob-Actually-delete-temporary-bitmap-on-failed-active-commit.patch b/SOURCES/libvirt-qemu-blockjob-Actually-delete-temporary-bitmap-on-failed-active-commit.patch
new file mode 100644
index 0000000..3edbf3b
--- /dev/null
+++ b/SOURCES/libvirt-qemu-blockjob-Actually-delete-temporary-bitmap-on-failed-active-commit.patch
@@ -0,0 +1,65 @@
+From 2069251b1f50e1aaec566909478f1443ccfe32e6 Mon Sep 17 00:00:00 2001
+Message-Id: <2069251b1f50e1aaec566909478f1443ccfe32e6@dist-git>
+From: Peter Krempa
+Date: Tue, 21 Jul 2020 13:56:22 +0200
+Subject: [PATCH] qemu: blockjob: Actually delete temporary bitmap on failed
+ active commit
+
+Commit 20a7abc2d2d tried to delete the possibly leftover bitmap but
+neglected to call the actual monitor to do so.
+
+Signed-off-by: Peter Krempa
+Reviewed-by: Eric Blake
+(cherry picked from commit 378e4fbc795c607485799cbd060f34483f580544)
+
+rhel-8.3: https://bugzilla.redhat.com/show_bug.cgi?id=1857779
+rhel-av-8.2.1: not cloned yet
+Message-Id:
+
+Reviewed-by: Jiri Denemark
+---
+ src/qemu/qemu_blockjob.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
+index 7e2df1445d..486fca31f3 100644
+--- a/src/qemu/qemu_blockjob.c
++++ b/src/qemu/qemu_blockjob.c
+@@ -1378,8 +1378,10 @@ qemuBlockJobProcessEventConcludedCopyAbort(virQEMUDriverPtr driver,
+ static void
+ qemuBlockJobProcessEventFailedActiveCommit(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+- qemuBlockJobDataPtr job)
++ qemuBlockJobDataPtr job,
++ qemuDomainAsyncJob asyncJob)
+ {
++ qemuDomainObjPrivatePtr priv = vm->privateData;
+ g_autoptr(virJSONValue) actions = virJSONValueNewArray();
+ virDomainDiskDefPtr disk = job->disk;
+
+@@ -1391,6 +1393,13 @@ qemuBlockJobProcessEventFailedActiveCommit(virQEMUDriverPtr driver,
+ ignore_value(qemuMonitorTransactionBitmapRemove(actions, disk->mirror->nodeformat,
+ "libvirt-tmp-activewrite"));
+
++ if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, asyncJob) < 0)
++ return;
++
++ qemuMonitorTransaction(priv->mon, &actions);
++
++ if (qemuDomainObjExitMonitor(priv->driver, vm) < 0)
++ return;
+
+ /* Ideally, we would make the backing chain read only again (yes, SELinux
+ * can do that using different labels). But that is not implemented yet and
+@@ -1515,7 +1524,7 @@ qemuBlockJobEventProcessConcludedTransition(qemuBlockJobDataPtr job,
+ if (success) {
+ qemuBlockJobProcessEventCompletedActiveCommit(driver, vm, job, asyncJob);
+ } else {
+- qemuBlockJobProcessEventFailedActiveCommit(driver, vm, job);
++ qemuBlockJobProcessEventFailedActiveCommit(driver, vm, job, asyncJob);
+ }
+ break;
+
+--
+2.27.0
+
diff --git a/SOURCES/libvirt-qemu-blockjob-Don-t-base-bitmap-handling-of-active-layer-block-commit-on-QEMU_CAPS_BLOCKDEV_REOPEN.patch b/SOURCES/libvirt-qemu-blockjob-Don-t-base-bitmap-handling-of-active-layer-block-commit-on-QEMU_CAPS_BLOCKDEV_REOPEN.patch
new file mode 100644
index 0000000..13d121b
--- /dev/null
+++ b/SOURCES/libvirt-qemu-blockjob-Don-t-base-bitmap-handling-of-active-layer-block-commit-on-QEMU_CAPS_BLOCKDEV_REOPEN.patch
@@ -0,0 +1,59 @@
+From 3c9641730c62ffae735d7984b3bc0632a9194b03 Mon Sep 17 00:00:00 2001
+Message-Id: <3c9641730c62ffae735d7984b3bc0632a9194b03@dist-git>
+From: Peter Krempa
+Date: Tue, 21 Jul 2020 13:56:21 +0200
+Subject: [PATCH] qemu: blockjob: Don't base bitmap handling of active-layer
+ block commit on QEMU_CAPS_BLOCKDEV_REOPEN
+
+The handler finalizing the active layer block commit doesn't actually
+reopen the file for active layer block commit, so the comment and check
+are invalid.
+
+Signed-off-by: Peter Krempa
+Reviewed-by: Eric Blake
+(cherry picked from commit d73f107469c8882a47ffbf1a55bd0b0370d6969e)
+
+rhel-8.3: https://bugzilla.redhat.com/show_bug.cgi?id=1857779
+rhel-av-8.2.1: not cloned yet
+Message-Id: <6946fb2535038e24dcef4884806c11c258f0fc70.1595332476.git.pkrempa@redhat.com>
+
+Reviewed-by: Jiri Denemark
+---
+ src/qemu/qemu_blockjob.c | 3 ++-
+ src/qemu/qemu_driver.c | 6 +-----
+ 2 files changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
+index 6e33f8666c..7e2df1445d 100644
+--- a/src/qemu/qemu_blockjob.c
++++ b/src/qemu/qemu_blockjob.c
+@@ -1063,7 +1063,8 @@ qemuBlockJobProcessEventCompletedCommitBitmaps(virDomainObjPtr vm,
+ g_autoptr(virJSONValue) actions = NULL;
+ bool active = job->type == QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT;
+
+- if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN))
++ if (!active &&
++ !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN))
+ return 0;
+
+ if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, asyncJob)))
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 9e3a455814..ad5ef7d67d 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -17631,11 +17631,7 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+ break;
+
+ case QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT:
+- /* we technically don't need reopen here, but we couldn't prepare
+- * the bitmaps if it wasn't present thus must skip this */
+- if (blockdev &&
+- virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN)) {
+-
++ if (blockdev) {
+ actions = virJSONValueNewArray();
+
+ if (qemuMonitorTransactionBitmapAdd(actions,
+--
+2.27.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
+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
+Reviewed-by: Daniel Henrique Barboza
+Signed-off-by: Ján Tomko
+Reviewed-by: Ján Tomko
+(cherry picked from commit c5815b31976f3982d18c7f6c1367ab6e403eb7eb)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1876297
+
+Signed-off-by: Jonathon Jongsma
+Message-Id: <20201204210242.822641-2-jjongsma@redhat.com>
+Reviewed-by: Michal Privoznik
+---
+ 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 @@
++
++ QEMUGuest2
++ c7a5fdbd-edaf-9455-926a-d65c16db1809
++ 219136
++ 219136
++ 1
++
++ hvm
++
++
++
++ destroy
++ restart
++ destroy
++
++ /usr/bin/qemu-system-i386
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+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
+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
+Reviewed-by: Daniel Henrique Barboza
+(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
+Message-Id: <20210121132406.337681-2-dbarboza@redhat.com>
+Reviewed-by: Pavel Hrdina
+---
+ 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
+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
+
+ $ 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
+Signed-off-by: Collin Walling
+Reviewed-by: Jiri Denemark
+(cherry picked from commit 9c6996124f4ef1635fbfe47090dadaf5a12b42e9)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1850680
+
+Signed-off-by: Tim Wiederhake
+Message-Id: <20201002081311.449901-2-twiederh@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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
+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
+Reviewed-by: Daniel Henrique Barboza
+(cherry picked from commit fe43b3a5a5532377f7de40e77ca9ffde5aa2ca7e)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik
+Message-Id: <4a0c05b78ac65e598b919acdb66d24a19fcf6251.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ 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:
+From: Michal Privoznik
+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
+(cherry picked from commit ccf627c110a178afa529818474e555bca62fc165)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik
+Message-Id:
+Reviewed-by: Ján Tomko
+---
+ 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-qemuDomainBlockPivot-Ignore-failures-of-creating-active-layer-bitmap.patch b/SOURCES/libvirt-qemuDomainBlockPivot-Ignore-failures-of-creating-active-layer-bitmap.patch
new file mode 100644
index 0000000..17a09fa
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainBlockPivot-Ignore-failures-of-creating-active-layer-bitmap.patch
@@ -0,0 +1,42 @@
+From 0084cc867b6de11a1b5ac1207ada57a3cc43acaf Mon Sep 17 00:00:00 2001
+Message-Id: <0084cc867b6de11a1b5ac1207ada57a3cc43acaf@dist-git>
+From: Peter Krempa
+Date: Tue, 21 Jul 2020 13:56:25 +0200
+Subject: [PATCH] qemuDomainBlockPivot: Ignore failures of creating active
+ layer bitmap
+
+Ignore errors from creating "libvirt-tmp-activewrite" bitmap. This
+prevents failures of finishing blockjobs if the bitmap already exists.
+
+Note that if the bitmap exists, the worst case that can happen is that
+more bits are marked as dirty in the resulting merge.
+
+Signed-off-by: Peter Krempa
+Reviewed-by: Eric Blake
+(cherry picked from commit 66dc4992fa8a51c4e774d32bcf75f26b1365e998)
+
+rhel-8.3: https://bugzilla.redhat.com/show_bug.cgi?id=1857779
+rhel-av-8.2.1: not cloned yet
+Message-Id: <9cec292732836005d59b50a0701acb804ed1dda5.1595332476.git.pkrempa@redhat.com>
+
+Reviewed-by: Jiri Denemark
+---
+ src/qemu/qemu_driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index 454d7b1c16..b5df0c63d4 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -17659,7 +17659,7 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+ }
+
+ if (bitmapactions && rc == 0)
+- rc = qemuMonitorTransaction(priv->mon, &bitmapactions);
++ ignore_value(qemuMonitorTransaction(priv->mon, &bitmapactions));
+
+ if (rc == 0)
+ ret = qemuMonitorJobComplete(priv->mon, job->name);
+--
+2.27.0
+
diff --git a/SOURCES/libvirt-qemuDomainBlockPivot-Rename-actions-to-bitmapactions.patch b/SOURCES/libvirt-qemuDomainBlockPivot-Rename-actions-to-bitmapactions.patch
new file mode 100644
index 0000000..3054d1d
--- /dev/null
+++ b/SOURCES/libvirt-qemuDomainBlockPivot-Rename-actions-to-bitmapactions.patch
@@ -0,0 +1,73 @@
+From 31a752d5bdd63d431b619ec5045b431fc3ca6bef Mon Sep 17 00:00:00 2001
+Message-Id: <31a752d5bdd63d431b619ec5045b431fc3ca6bef@dist-git>
+From: Peter Krempa
+Date: Tue, 21 Jul 2020 13:56:24 +0200
+Subject: [PATCH] qemuDomainBlockPivot: Rename 'actions' to 'bitmapactions'
+
+There are two possible 'transaction' command arguments in the function.
+Rename 'actions' as they deal with creating bitmaps only.
+
+Signed-off-by: Peter Krempa
+Reviewed-by: Eric Blake
+(cherry picked from commit 24ac1a7c04fded2f8639478abead72bb57506162)
+
+rhel-8.3: https://bugzilla.redhat.com/show_bug.cgi?id=1857779
+rhel-av-8.2.1: not cloned yet
+Message-Id: <6a3969721f1e701a16eb3679dcc37c9908c753ae.1595332476.git.pkrempa@redhat.com>
+
+Reviewed-by: Jiri Denemark
+---
+ src/qemu/qemu_driver.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index ad5ef7d67d..454d7b1c16 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -17564,7 +17564,7 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+ int ret = -1;
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
+- g_autoptr(virJSONValue) actions = NULL;
++ g_autoptr(virJSONValue) bitmapactions = NULL;
+ g_autoptr(virJSONValue) reopenactions = NULL;
+
+ if (job->state != QEMU_BLOCKJOB_STATE_READY) {
+@@ -17597,9 +17597,9 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+ bool shallow = job->jobflags & VIR_DOMAIN_BLOCK_COPY_SHALLOW;
+ bool reuse = job->jobflags & VIR_DOMAIN_BLOCK_COPY_REUSE_EXT;
+
+- actions = virJSONValueNewArray();
++ bitmapactions = virJSONValueNewArray();
+
+- if (qemuMonitorTransactionBitmapAdd(actions,
++ if (qemuMonitorTransactionBitmapAdd(bitmapactions,
+ disk->mirror->nodeformat,
+ "libvirt-tmp-activewrite",
+ false,
+@@ -17632,9 +17632,9 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+
+ case QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT:
+ if (blockdev) {
+- actions = virJSONValueNewArray();
++ bitmapactions = virJSONValueNewArray();
+
+- if (qemuMonitorTransactionBitmapAdd(actions,
++ if (qemuMonitorTransactionBitmapAdd(bitmapactions,
+ job->data.commit.base->nodeformat,
+ "libvirt-tmp-activewrite",
+ false,
+@@ -17658,8 +17658,8 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
+ }
+ }
+
+- if (actions && rc == 0)
+- rc = qemuMonitorTransaction(priv->mon, &actions);
++ if (bitmapactions && rc == 0)
++ rc = qemuMonitorTransaction(priv->mon, &bitmapactions);
+
+ if (rc == 0)
+ ret = qemuMonitorJobComplete(priv->mon, job->name);
+--
+2.27.0
+
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
+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
+Reviewed-by: Andrea Bolognani
+(cherry picked from commit c43622f06e295edcb9cedf33583f0bd18fb04b10)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1880418
+
+Signed-off-by: Michal Privoznik
+Message-Id: <9b91110a238eba22f4b876e7b15a25d5113ee91e.1602069592.git.mprivozn@redhat.com>
+Reviewed-by: Andrea Bolognani
+---
+ 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
+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
+Reviewed-by: Daniel Henrique Barboza
+(cherry picked from commit 8ba1792785e17736db866d62b68812a9c7e7ca40)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik
+Message-Id:
+Reviewed-by: Ján Tomko
+---
+ 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
+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
+Reviewed-by: Daniel Henrique Barboza
+(cherry picked from commit afb1ea67769d88290499c5c6a0c34982bad6e9c9)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik
+Message-Id: <6974ab2c0987840742965ea925adcc4395f72ec2.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ .../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 @@
++
++ QEMUGuest
++ c7a5fdb2-cdaf-9455-926a-d65c16db1809
++ 8388608
++ 8388608
++ 12
++
++ hvm
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++ |
++
++
++
++
++
++
++
++
++
++ |
++
++
++
++
++
++
++
++
++
++ |
++
++
++
++
++
++
++
++
++
++ |
++
++
++
++
++
++
++
++
++
++ |
++
++
++
++
++
++
++
++
++
++ |
++
++
++
++ destroy
++ restart
++ restart
++
++ /usr/bin/qemu-system-x86_64
++
++
++
++
++
++
++
++
++
++
++
+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:
+From: =?UTF-8?q?J=C3=A1n=20Tomko?=
+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
+(cherry picked from commit 50864dcda191eb35732dbd80fb6ca251a6bba923)
+Signed-off-by: Ján Tomko
+Message-Id: <7900a5f9e8479789a5cc427a85f385095e517e87.1601383236.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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: :
+ * - @acl: ::
++ * - @acl: ::: :
+ *
+ * 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 {
+ * is one of the permissions in access/viraccessperm.h
+ * indicates the rule only applies if the named flag
+ * is set in the API call
++ * and can be used to check an unsigned int parameter
++ * against value
+ *
+ * - @aclfilter: :
+ *
+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:
+From: =?UTF-8?q?J=C3=A1n=20Tomko?=
+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 in remote_protocol.x
+@acl annotations:
+ @acl: ::
+so that we can add more fields after, e.g.:
+ @acl: :::
+
+Signed-off-by: Ján Tomko
+(cherry picked from commit 955029bd0ad7ef96000f529ac38204a8f4a96401)
+Signed-off-by: Ján Tomko
+Message-Id: <5fda9fc6cfe45eace10b8c2565a8b0c46b51f46c.1601383236.git.jtomko@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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?=
+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
+Reported-by: Ilja Van Sprundel
+(cherry picked from commit e4116eaa44cb366b59f7fe98f4b88d04c04970ad)
+Signed-off-by: Ján Tomko
+
+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
+---
+ 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-src-assume-sys-sysmacros.h-always-exists-on-Linux.patch b/SOURCES/libvirt-src-assume-sys-sysmacros.h-always-exists-on-Linux.patch
new file mode 100644
index 0000000..dc51d5e
--- /dev/null
+++ b/SOURCES/libvirt-src-assume-sys-sysmacros.h-always-exists-on-Linux.patch
@@ -0,0 +1,168 @@
+From 06e0a9d40c52736919f32578f926bf4d829e77ec Mon Sep 17 00:00:00 2001
+Message-Id: <06e0a9d40c52736919f32578f926bf4d829e77ec@dist-git>
+From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?=
+Date: Mon, 27 Jul 2020 12:36:49 +0200
+Subject: [PATCH] src: assume sys/sysmacros.h always exists on Linux
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+All our supported Linux distros now have this header.
+It has never existed on FreeBSD / macOS / Mingw.
+
+Reviewed-by: Pavel Hrdina
+Signed-off-by: Daniel P. Berrangé
+(cherry picked from commit 03c532cf9711dd6ad35380455a77141ef7d492ab)
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1860421
+
+Conflicts:
+- src/util/virutil.c - context, because
+ db72866310d1e520efa8ed2d4589bdb5e76a1c95 (util: add API for
+ reading password from the console) isn't backported.
+
+Signed-off-by: Michal Privoznik
+Message-Id:
+Reviewed-by: Jiri Denemark
+---
+ src/conf/domain_audit.c | 4 +---
+ src/lxc/lxc_controller.c | 4 +---
+ src/lxc/lxc_driver.c | 4 +---
+ src/qemu/qemu_domain.c | 4 +---
+ src/util/vircgroup.c | 8 +-------
+ src/util/virdevmapper.c | 4 +---
+ src/util/virutil.c | 4 +---
+ tests/vircgroupmock.c | 8 +-------
+ 8 files changed, 8 insertions(+), 32 deletions(-)
+
+diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
+index fdccc585fb..6d3579e0f6 100644
+--- a/src/conf/domain_audit.c
++++ b/src/conf/domain_audit.c
+@@ -23,9 +23,7 @@
+
+ #include
+
+-#ifdef MAJOR_IN_MKDEV
+-# include
+-#elif MAJOR_IN_SYSMACROS
++#ifdef __linux__
+ # include
+ #endif
+
+diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
+index 42c631ed0b..0da89dba89 100644
+--- a/src/lxc/lxc_controller.c
++++ b/src/lxc/lxc_controller.c
+@@ -25,9 +25,7 @@
+ #include
+ #include
+
+-#ifdef MAJOR_IN_MKDEV
+-# include
+-#elif MAJOR_IN_SYSMACROS
++#ifdef __linux__
+ # include
+ #endif
+
+diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
+index 780c6ed4a2..a8c93dd228 100644
+--- a/src/lxc/lxc_driver.c
++++ b/src/lxc/lxc_driver.c
+@@ -25,9 +25,7 @@
+ #include
+ #include
+
+-#ifdef MAJOR_IN_MKDEV
+-# include
+-#elif MAJOR_IN_SYSMACROS
++#ifdef __linux__
+ # include
+ #endif
+
+diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
+index 1e968368ae..ffe88ff027 100644
+--- a/src/qemu/qemu_domain.c
++++ b/src/qemu/qemu_domain.c
+@@ -64,9 +64,7 @@
+ #include "backup_conf.h"
+ #include "virdevmapper.h"
+
+-#ifdef MAJOR_IN_MKDEV
+-# include
+-#elif MAJOR_IN_SYSMACROS
++#ifdef __linux__
+ # include
+ #endif
+ #include
+diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
+index dff2f6fd3a..a45c2e7f2f 100644
+--- a/src/util/vircgroup.c
++++ b/src/util/vircgroup.c
+@@ -25,13 +25,7 @@
+ # include
+ # include
+ # include
+-
+-# ifdef MAJOR_IN_MKDEV
+-# include
+-# elif MAJOR_IN_SYSMACROS
+-# include
+-# endif
+-
++# include
+ # include
+ # include
+ # include
+diff --git a/src/util/virdevmapper.c b/src/util/virdevmapper.c
+index c346432d86..40a82285f9 100644
+--- a/src/util/virdevmapper.c
++++ b/src/util/virdevmapper.c
+@@ -20,9 +20,7 @@
+
+ #include
+
+-#ifdef MAJOR_IN_MKDEV
+-# include
+-#elif MAJOR_IN_SYSMACROS
++#ifdef __linux__
+ # include
+ #endif
+
+diff --git a/src/util/virutil.c b/src/util/virutil.c
+index 17fd06dbb2..5e6bbb37c0 100644
+--- a/src/util/virutil.c
++++ b/src/util/virutil.c
+@@ -28,9 +28,7 @@
+ #include
+ #include
+
+-#ifdef MAJOR_IN_MKDEV
+-# include
+-#elif MAJOR_IN_SYSMACROS
++#ifdef __linux__
+ # include
+ #endif
+
+diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c
+index 9ec3b576d2..66b8c01852 100644
+--- a/tests/vircgroupmock.c
++++ b/tests/vircgroupmock.c
+@@ -23,13 +23,7 @@
+ # include
+ # include
+ # include
+-
+-# ifdef MAJOR_IN_MKDEV
+-# include
+-# elif MAJOR_IN_SYSMACROS
+-# include
+-# endif
+-
++# include
+ # include
+ # include "testutilslxc.h"
+ # include "virstring.h"
+--
+2.28.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
+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
+Reviewed-by: Daniel Henrique Barboza
+(cherry picked from commit e9693502fb63ce5ddd07d2599daddc563c422eed)
+Message-Id: <20210116035151.1066734-5-laine@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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
+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
+Reviewed-by: Michal Privoznik
+(cherry picked from commit 99dcdf505e0856a5ebfb31f0047a1e24ec60b557)
+
+Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518
+
+Signed-off-by: Michal Privoznik
+Message-Id: <4af6d896e777397acd8b5945da6bf6bf071f2e98.1602087923.git.mprivozn@redhat.com>
+Reviewed-by: Ján Tomko
+---
+ 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 @@
+ 8388608
+ 12
+
+- hvm
++ hvm
+
+
+
+--
+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
+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
+Reviewed-by: Erik Skultety
+Signed-off-by: Marc Hartmayer
+(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
+---
+ 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:
+From: Dmytro Linkin
+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
+Signed-off-by: Dmytro Linkin
+Reviewed-by: Adrian Chiris
+Reviewed-by: Laine Stump
+(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
+Message-Id: <20210129041729.1076345-4-laine@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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
+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
+Reviewed-by: Laine Stump
+(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
+Message-Id: <20210129041729.1076345-2-laine@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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
++ * , 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
+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
+Reviewed-by: Daniel Henrique Barboza
+(cherry picked from commit 56dd128bd06c38fab4256a098124d47d803e919a)
+Message-Id: <20210116035151.1066734-7-laine@redhat.com>
+Reviewed-by: Jiri Denemark
+---
+ 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
+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
+Reviewed-by: Michal Privoznik
+(cherry picked from commit 95089f481e003d971fe0a082018216c58c1b80e5)
+
+https://bugzilla.redhat.com/1874304
+Signed-off-by: Laine Stump
+Message-Id: <20201213030453.48851-3-laine@redhat.com>
+Reviewed-by: Michal Privoznik
+---
+ 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
+ #endif
++#include
+
+ #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