diff --git a/SOURCES/libvirt-Add-testdata-for-AMD-EPYC-7502.patch b/SOURCES/libvirt-Add-testdata-for-AMD-EPYC-7502.patch new file mode 100644 index 0000000..1530f4e --- /dev/null +++ b/SOURCES/libvirt-Add-testdata-for-AMD-EPYC-7502.patch @@ -0,0 +1,2173 @@ +From a2f2e97422de810517a77d8f098564e3b6c0f7c2 Mon Sep 17 00:00:00 2001 +Message-Id: <a2f2e97422de810517a77d8f098564e3b6c0f7c2@dist-git> +From: Markus Schade <markus.schade@hetzner.com> +Date: Thu, 8 Oct 2020 18:01:24 +0200 +Subject: [PATCH] Add testdata for AMD EPYC 7502 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Markus Schade <markus.schade@hetzner.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +(cherry picked from commit e06590f1708a599286f3ee3690b3dc50ee525d40) + +https://bugzilla.redhat.com/show_bug.cgi?id=1861506 + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Message-Id: <2efe44ce5c929916c92656803d39635ae7c189b9.1602172344.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + tests/cputest.c | 1 + + ...86_64-cpuid-EPYC-7502-32-Core-disabled.xml | 9 + + ...x86_64-cpuid-EPYC-7502-32-Core-enabled.xml | 11 + + .../x86_64-cpuid-EPYC-7502-32-Core-guest.xml | 42 + + .../x86_64-cpuid-EPYC-7502-32-Core-host.xml | 43 + + .../x86_64-cpuid-EPYC-7502-32-Core-json.xml | 31 + + .../x86_64-cpuid-EPYC-7502-32-Core.json | 1866 +++++++++++++++++ + .../x86_64-cpuid-EPYC-7502-32-Core.sig | 4 + + .../x86_64-cpuid-EPYC-7502-32-Core.xml | 66 + + 9 files changed, 2073 insertions(+) + create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-disabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-enabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.json + create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.xml + +diff --git a/tests/cputest.c b/tests/cputest.c +index 68e8eb0290..388174eba7 100644 +--- a/tests/cputest.c ++++ b/tests/cputest.c +@@ -1242,6 +1242,7 @@ mymain(void) + DO_TEST_CPUID(VIR_ARCH_X86_64, "Hygon-C86-7185-32-core", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "EPYC-7601-32-Core", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "EPYC-7601-32-Core-ibpb", JSON_MODELS_REQUIRED); ++ DO_TEST_CPUID(VIR_ARCH_X86_64, "EPYC-7502-32-Core", JSON_MODELS); + DO_TEST_CPUID(VIR_ARCH_X86_64, "FX-8150", JSON_NONE); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Opteron-1352", JSON_NONE); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Opteron-2350", JSON_HOST); +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-disabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-disabled.xml +new file mode 100644 +index 0000000000..ca71b9efb5 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-disabled.xml +@@ -0,0 +1,9 @@ ++<!-- Features disabled by QEMU --> ++<cpudata arch='x86'> ++ <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x08000008' edx='0x10000000'/> ++ <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x00001000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/> ++ <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01423408' edx='0x00000000'/> ++ <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x000014f6'/> ++</cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-enabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-enabled.xml +new file mode 100644 +index 0000000000..09a9952c27 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-enabled.xml +@@ -0,0 +1,11 @@ ++<!-- Features enabled by QEMU --> ++<cpudata arch='x86'> ++ <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0xf7f83203' edx='0x078bfbff'/> ++ <cpuid eax_in='0x00000006' ecx_in='0x00' eax='0x00000004' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x219c01ab' ecx='0x00400004' edx='0xac000000'/> ++ <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x0000000f' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x008003f7' edx='0x2e500800'/> ++ <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x03009205' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/> ++ <msr index='0x10a' edx='0x00000000' eax='0x00000069'/> ++</cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml +new file mode 100644 +index 0000000000..1320f65a58 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml +@@ -0,0 +1,42 @@ ++<cpu mode='custom' match='exact'> ++ <model fallback='forbid'>EPYC-IBPB</model> ++ <vendor>AMD</vendor> ++ <feature policy='require' name='ht'/> ++ <feature policy='require' name='osxsave'/> ++ <feature policy='require' name='cmt'/> ++ <feature policy='require' name='clwb'/> ++ <feature policy='require' name='umip'/> ++ <feature policy='require' name='rdpid'/> ++ <feature policy='require' name='xsaves'/> ++ <feature policy='require' name='mbm_total'/> ++ <feature policy='require' name='mbm_local'/> ++ <feature policy='require' name='cmp_legacy'/> ++ <feature policy='require' name='extapic'/> ++ <feature policy='require' name='ibs'/> ++ <feature policy='require' name='skinit'/> ++ <feature policy='require' name='wdt'/> ++ <feature policy='require' name='tce'/> ++ <feature policy='require' name='topoext'/> ++ <feature policy='require' name='perfctr_core'/> ++ <feature policy='require' name='perfctr_nb'/> ++ <feature policy='require' name='invtsc'/> ++ <feature policy='require' name='clzero'/> ++ <feature policy='require' name='xsaveerptr'/> ++ <feature policy='require' name='wbnoinvd'/> ++ <feature policy='require' name='amd-stibp'/> ++ <feature policy='require' name='amd-ssbd'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='lbrv'/> ++ <feature policy='require' name='svm-lock'/> ++ <feature policy='require' name='nrip-save'/> ++ <feature policy='require' name='tsc-scale'/> ++ <feature policy='require' name='vmcb-clean'/> ++ <feature policy='require' name='flushbyasid'/> ++ <feature policy='require' name='decodeassists'/> ++ <feature policy='require' name='pause-filter'/> ++ <feature policy='require' name='pfthreshold'/> ++ <feature policy='require' name='rdctl-no'/> ++ <feature policy='require' name='skip-l1dfl-vmentry'/> ++ <feature policy='require' name='mds-no'/> ++ <feature policy='require' name='pschange-mc-no'/> ++</cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml +new file mode 100644 +index 0000000000..37905ec812 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml +@@ -0,0 +1,43 @@ ++<cpu> ++ <arch>x86_64</arch> ++ <model>EPYC-IBPB</model> ++ <vendor>AMD</vendor> ++ <feature name='ht'/> ++ <feature name='osxsave'/> ++ <feature name='cmt'/> ++ <feature name='clwb'/> ++ <feature name='umip'/> ++ <feature name='rdpid'/> ++ <feature name='xsaves'/> ++ <feature name='mbm_total'/> ++ <feature name='mbm_local'/> ++ <feature name='cmp_legacy'/> ++ <feature name='extapic'/> ++ <feature name='ibs'/> ++ <feature name='skinit'/> ++ <feature name='wdt'/> ++ <feature name='tce'/> ++ <feature name='topoext'/> ++ <feature name='perfctr_core'/> ++ <feature name='perfctr_nb'/> ++ <feature name='invtsc'/> ++ <feature name='clzero'/> ++ <feature name='xsaveerptr'/> ++ <feature name='wbnoinvd'/> ++ <feature name='amd-stibp'/> ++ <feature name='amd-ssbd'/> ++ <feature name='npt'/> ++ <feature name='lbrv'/> ++ <feature name='svm-lock'/> ++ <feature name='nrip-save'/> ++ <feature name='tsc-scale'/> ++ <feature name='vmcb-clean'/> ++ <feature name='flushbyasid'/> ++ <feature name='decodeassists'/> ++ <feature name='pause-filter'/> ++ <feature name='pfthreshold'/> ++ <feature name='rdctl-no'/> ++ <feature name='skip-l1dfl-vmentry'/> ++ <feature name='mds-no'/> ++ <feature name='pschange-mc-no'/> ++</cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml +new file mode 100644 +index 0000000000..225cf63852 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml +@@ -0,0 +1,31 @@ ++<cpu mode='custom' match='exact'> ++ <model fallback='forbid'>EPYC-IBPB</model> ++ <vendor>AMD</vendor> ++ <feature policy='require' name='x2apic'/> ++ <feature policy='require' name='tsc-deadline'/> ++ <feature policy='require' name='hypervisor'/> ++ <feature policy='require' name='tsc_adjust'/> ++ <feature policy='require' name='clwb'/> ++ <feature policy='require' name='umip'/> ++ <feature policy='require' name='rdpid'/> ++ <feature policy='require' name='spec-ctrl'/> ++ <feature policy='require' name='stibp'/> ++ <feature policy='require' name='arch-capabilities'/> ++ <feature policy='require' name='ssbd'/> ++ <feature policy='require' name='xsaves'/> ++ <feature policy='require' name='cmp_legacy'/> ++ <feature policy='require' name='perfctr_core'/> ++ <feature policy='require' name='clzero'/> ++ <feature policy='require' name='xsaveerptr'/> ++ <feature policy='require' name='wbnoinvd'/> ++ <feature policy='require' name='amd-stibp'/> ++ <feature policy='require' name='amd-ssbd'/> ++ <feature policy='require' name='virt-ssbd'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='nrip-save'/> ++ <feature policy='require' name='rdctl-no'/> ++ <feature policy='require' name='skip-l1dfl-vmentry'/> ++ <feature policy='require' name='mds-no'/> ++ <feature policy='require' name='pschange-mc-no'/> ++ <feature policy='disable' name='monitor'/> ++</cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.json b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.json +new file mode 100644 +index 0000000000..06c265d829 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.json +@@ -0,0 +1,1866 @@ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "vmx-entry-load-rtit-ctl": false, ++ "phys-bits": 0, ++ "core-id": -1, ++ "xlevel": 2147483679, ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "vmx-apicv-xapic": false, ++ "mmx": true, ++ "arat": true, ++ "rdpid": true, ++ "vmx-page-walk-5": false, ++ "vmx-page-walk-4": false, ++ "vmx-desc-exit": false, ++ "gfni": false, ++ "ibrs-all": false, ++ "pause-filter": false, ++ "xsavec": true, ++ "intel-pt": false, ++ "vmx-cr8-store-exit": false, ++ "hv-frequencies": false, ++ "tsc-frequency": 0, ++ "vmx-rdseed-exit": false, ++ "xd": true, ++ "x-intel-pt-auto-level": true, ++ "hv-vendor-id": "", ++ "vmx-eptp-switching": false, ++ "kvm_asyncpf": true, ++ "kvm-asyncpf": true, ++ "perfctr_core": true, ++ "perfctr-core": true, ++ "mpx": false, ++ "avx512cd": false, ++ "pbe": false, ++ "decodeassists": false, ++ "vmx-exit-clear-bndcfgs": false, ++ "vmx-exit-load-efer": false, ++ "sse4_1": true, ++ "sse4-1": true, ++ "sse4.1": true, ++ "family": 23, ++ "legacy-cache": true, ++ "vmx-vmwrite-vmexit-fields": false, ++ "vmx-vnmi": false, ++ "vmx-true-ctls": false, ++ "host-phys-bits-limit": 0, ++ "vmx-ept-execonly": false, ++ "vmx-exit-save-efer": false, ++ "vmx-invept-all-context": false, ++ "vmware-cpuid-freq": true, ++ "wbnoinvd": true, ++ "avx512f": false, ++ "xcrypt": false, ++ "hv-runtime": false, ++ "hv-stimer-direct": false, ++ "mce": true, ++ "mca": true, ++ "msr": true, ++ "thread-id": -1, ++ "vmx-exit-load-pat": false, ++ "vmx-intr-exit": false, ++ "min-level": 16, ++ "vmx-flexpriority": false, ++ "xgetbv1": true, ++ "cid": false, ++ "hv-relaxed": false, ++ "avx512-bf16": false, ++ "ds": false, ++ "hv-crash": false, ++ "fxsr": true, ++ "vmx-cr8-load-exit": false, ++ "xsaveopt": true, ++ "vmx-apicv-vid": false, ++ "vmx-exit-save-pat": false, ++ "tsx-ctrl": false, ++ "xtpr": false, ++ "vmx-ple": false, ++ "hv-evmcs": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "avx512vl": false, ++ "extapic": false, ++ "vmx-vmfunc": false, ++ "3dnowprefetch": true, ++ "vmx-activity-shutdown": false, ++ "avx512vbmi2": false, ++ "cr8legacy": true, ++ "vmx-encls-exit": false, ++ "stibp": true, ++ "vmx-msr-bitmap": false, ++ "cpuid-0xb": true, ++ "xcrypt-en": false, ++ "vmx-mwait-exit": false, ++ "kvm_pv_eoi": true, ++ "vmx-pml": false, ++ "apic-id": 4294967295, ++ "vmx-nmi-exit": false, ++ "vmx-invept-single-context-noglobals": false, ++ "pn": false, ++ "rsba": false, ++ "dca": false, ++ "vmx-unrestricted-guest": false, ++ "vendor": "AuthenticAMD", ++ "hv-ipi": false, ++ "vmx-cr3-store-noexit": false, ++ "pku": false, ++ "smx": false, ++ "cmp-legacy": true, ++ "cmp_legacy": true, ++ "node-id": -1, ++ "avx512-4fmaps": false, ++ "vmcb_clean": false, ++ "vmcb-clean": false, ++ "hle": false, ++ "amd-no-ssb": false, ++ "3dnowext": false, ++ "npt": true, ++ "rdctl-no": true, ++ "vmx-invvpid": false, ++ "memory": "/machine/unattached/system[0]", ++ "clwb": true, ++ "lbrv": false, ++ "adx": true, ++ "ss": false, ++ "pni": true, ++ "svm_lock": false, ++ "svm-lock": false, ++ "pfthreshold": false, ++ "smap": true, ++ "smep": true, ++ "vmx-invpcid-exit": false, ++ "x2apic": true, ++ "avx512vnni": false, ++ "avx512vbmi": false, ++ "vmx-apicv-x2apic": false, ++ "hv-stimer": false, ++ "kvm-pv-sched-yield": true, ++ "vmx-invlpg-exit": false, ++ "x-hv-synic-kvm-only": false, ++ "vmx-invvpid-all-context": false, ++ "i64": true, ++ "vmx-activity-hlt": false, ++ "flushbyasid": false, ++ "f16c": true, ++ "vmx-exit-ack-intr": false, ++ "ace2-en": false, ++ "pae": true, ++ "pat": true, ++ "sse": true, ++ "die-id": -1, ++ "vmx-tsc-offset": false, ++ "phe-en": false, ++ "kvm_nopiodelay": true, ++ "kvm-nopiodelay": true, ++ "tm": false, ++ "kvmclock-stable-bit": true, ++ "vmx-rdtsc-exit": false, ++ "hypervisor": true, ++ "vmx-rdtscp-exit": false, ++ "socket-id": -1, ++ "mds-no": true, ++ "pcommit": false, ++ "vmx-vpid": false, ++ "syscall": true, ++ "level": 16, ++ "avx512dq": false, ++ "x-migrate-smi-count": true, ++ "svm": true, ++ "full-cpuid-auto-level": true, ++ "hv-reset": false, ++ "invtsc": false, ++ "vmx-monitor-exit": false, ++ "sse3": true, ++ "sse2": true, ++ "ssbd": true, ++ "vmx-wbinvd-exit": false, ++ "est": false, ++ "kvm-poll-control": true, ++ "kvm_poll_control": true, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-eoi": true, ++ "kvm-pv-ipi": true, ++ "cx8": true, ++ "vmx-invvpid-single-addr": false, ++ "waitpkg": false, ++ "cldemote": false, ++ "vmx-ept": false, ++ "hv-reenlightenment": false, ++ "kvm_mmu": false, ++ "kvm-mmu": false, ++ "sse4-2": true, ++ "sse4.2": true, ++ "sse4_2": true, ++ "pge": true, ++ "fill-mtrr-mask": true, ++ "avx512bitalg": false, ++ "vmx-entry-load-bndcfgs": false, ++ "nodeid_msr": false, ++ "pdcm": false, ++ "vmx-exit-clear-rtit-ctl": false, ++ "model": 49, ++ "movbe": true, ++ "nrip_save": true, ++ "nrip-save": true, ++ "vmx-pause-exit": false, ++ "ssse3": true, ++ "kvm_pv_unhalt": true, ++ "sse4a": true, ++ "invpcid": false, ++ "pdpe1gb": true, ++ "tsc-deadline": true, ++ "skip-l1dfl-vmentry": true, ++ "vmx-exit-load-perf-global-ctrl": false, ++ "fma": true, ++ "cx16": true, ++ "de": true, ++ "enforce": false, ++ "stepping": 0, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ds-cpl": false, ++ "ds_cpl": false, ++ "ibs": false, ++ "fma4": false, ++ "host-phys-bits": false, ++ "vmx-exit-nosave-debugctl": false, ++ "vmx-invept": false, ++ "la57": false, ++ "osvw": true, ++ "check": true, ++ "hv-spinlocks": 4294967295, ++ "vmx-eptad": false, ++ "pmu": false, ++ "vmx-entry-noload-debugctl": false, ++ "pmm": false, ++ "apic": true, ++ "spec-ctrl": true, ++ "vmx-posted-intr": false, ++ "vmx-apicv-register": false, ++ "min-xlevel2": 0, ++ "tsc-adjust": true, ++ "tsc_adjust": true, ++ "kvm-steal-time": true, ++ "kvm_steal_time": true, ++ "kvmclock": true, ++ "vmx-zero-len-inject": false, ++ "l3-cache": true, ++ "pschange-mc-no": true, ++ "vmx-rdrand-exit": false, ++ "lwp": false, ++ "hv-passthrough": false, ++ "amd-ssbd": true, ++ "ibpb": true, ++ "xop": false, ++ "core-capability": false, ++ "avx": true, ++ "vmx-invept-single-context": false, ++ "movdiri": false, ++ "avx512bw": false, ++ "acpi": false, ++ "ace2": false, ++ "fsgsbase": true, ++ "hv-vapic": false, ++ "vmx-ept-1gb": false, ++ "vmx-ept-2mb": false, ++ "ht": false, ++ "vmx-io-exit": false, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": true, ++ "popcnt": true, ++ "vaes": false, ++ "xsaves": true, ++ "movdir64b": false, ++ "vmx-shadow-vmcs": false, ++ "tcg-cpuid": true, ++ "lm": true, ++ "vmx-exit-save-preemption-timer": false, ++ "vmx-entry-load-pat": false, ++ "vmx-entry-load-perf-global-ctrl": false, ++ "vmx-io-bitmap": false, ++ "vmx-store-lma": false, ++ "umip": true, ++ "vmx-movdr-exit": false, ++ "avx2": true, ++ "pse": true, ++ "pclmuldq": true, ++ "sep": true, ++ "vmx-cr3-load-noexit": false, ++ "virt-ssbd": true, ++ "x-hv-max-vps": -1, ++ "nodeid-msr": false, ++ "md-clear": false, ++ "split-lock-detect": false, ++ "kvm": true, ++ "misalignsse": true, ++ "min-xlevel": 2147483679, ++ "realized": false, ++ "kvm-pv-unhalt": true, ++ "bmi2": true, ++ "bmi1": true, ++ "tsc_scale": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "amd-stibp": true, ++ "hv-vpindex": false, ++ "hv-no-nonarch-coresharing": "off", ++ "vmx-preemption-timer": false, ++ "xlevel2": 0, ++ "clflushopt": true, ++ "vmx-vnmi-pending": false, ++ "kvm-no-smi-migration": false, ++ "monitor": false, ++ "vmx-vintr-pending": false, ++ "avx512er": false, ++ "pmm-en": false, ++ "taa-no": false, ++ "pcid": false, ++ "vmx-secondary-ctls": false, ++ "arch-capabilities": true, ++ "vmx-xsaves": false, ++ "clzero": true, ++ "3dnow": false, ++ "erms": false, ++ "x-force-features": false, ++ "vmx-entry-ia32e-mode": false, ++ "lahf-lm": true, ++ "lahf_lm": true, ++ "vmx-ins-outs": false, ++ "vpclmulqdq": false, ++ "xstore": false, ++ "fxsr-opt": true, ++ "fxsr_opt": true, ++ "hv-synic": false, ++ "rtm": false, ++ "kvm-hint-dedicated": false, ++ "lmce": false, ++ "hv-time": false, ++ "perfctr_nb": false, ++ "perfctr-nb": false, ++ "hv-tlbflush": false, ++ "ffxsr": true, ++ "rdrand": true, ++ "rdseed": true, ++ "avx512-4vnniw": false, ++ "vme": true, ++ "vmx": false, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "xsaveerptr": true, ++ "pse36": true, ++ "kvm-pv-tlb-flush": true, ++ "vmx-activity-wait-sipi": false, ++ "tbm": false, ++ "vmx-rdpmc-exit": false, ++ "wdt": false, ++ "vmx-entry-load-efer": false, ++ "level-func7": 0, ++ "vmx-mtf": false, ++ "pause_filter": false, ++ "model-id": "AMD EPYC 7502 32-Core Processor ", ++ "sha-ni": true, ++ "abm": true, ++ "vmx-ept-advanced-exitinfo": false, ++ "avx512pf": false, ++ "vmx-hlt-exit": false, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "model-expansion" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "max", ++ "typename": "max-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "host", ++ "typename": "host-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "base", ++ "typename": "base-x86_64-cpu", ++ "unavailable-features": [], ++ "static": true, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu64-v1", ++ "typename": "qemu64-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu64", ++ "typename": "qemu64-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "qemu64-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu32-v1", ++ "typename": "qemu32-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu32", ++ "typename": "qemu32-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "qemu32-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "phenom-v1", ++ "typename": "phenom-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "3dnowext", ++ "3dnow" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "phenom", ++ "typename": "phenom-x86_64-cpu", ++ "unavailable-features": [ ++ "3dnowext", ++ "3dnow" ++ ], ++ "alias-of": "phenom-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium3-v1", ++ "typename": "pentium3-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium3", ++ "typename": "pentium3-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "pentium3-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium2-v1", ++ "typename": "pentium2-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium2", ++ "typename": "pentium2-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "pentium2-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium-v1", ++ "typename": "pentium-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium", ++ "typename": "pentium-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "pentium-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "n270-v1", ++ "typename": "n270-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "ss" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "n270", ++ "typename": "n270-x86_64-cpu", ++ "unavailable-features": [ ++ "ss" ++ ], ++ "alias-of": "n270-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm64-v1", ++ "typename": "kvm64-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm64", ++ "typename": "kvm64-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "kvm64-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm32-v1", ++ "typename": "kvm32-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm32", ++ "typename": "kvm32-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "kvm32-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "coreduo-v1", ++ "typename": "coreduo-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "ss" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "coreduo", ++ "typename": "coreduo-x86_64-cpu", ++ "unavailable-features": [ ++ "ss" ++ ], ++ "alias-of": "coreduo-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "core2duo-v1", ++ "typename": "core2duo-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "ss" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "core2duo", ++ "typename": "core2duo-x86_64-cpu", ++ "unavailable-features": [ ++ "ss" ++ ], ++ "alias-of": "core2duo-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "athlon-v1", ++ "typename": "athlon-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "3dnowext", ++ "3dnow" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "athlon", ++ "typename": "athlon-x86_64-cpu", ++ "unavailable-features": [ ++ "3dnowext", ++ "3dnow" ++ ], ++ "alias-of": "athlon-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere-v2", ++ "typename": "Westmere-v2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere-v1", ++ "typename": "Westmere-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere-IBRS", ++ "typename": "Westmere-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "Westmere-v2", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere", ++ "typename": "Westmere-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "Westmere-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Snowridge-v2", ++ "typename": "Snowridge-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "erms", ++ "gfni", ++ "cldemote", ++ "movdiri", ++ "movdir64b", ++ "core-capability", ++ "split-lock-detect" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Snowridge-v1", ++ "typename": "Snowridge-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "erms", ++ "mpx", ++ "gfni", ++ "cldemote", ++ "movdiri", ++ "movdir64b", ++ "core-capability", ++ "mpx", ++ "mpx", ++ "split-lock-detect" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Snowridge", ++ "typename": "Snowridge-x86_64-cpu", ++ "unavailable-features": [ ++ "erms", ++ "mpx", ++ "gfni", ++ "cldemote", ++ "movdiri", ++ "movdir64b", ++ "core-capability", ++ "mpx", ++ "mpx", ++ "split-lock-detect" ++ ], ++ "alias-of": "Snowridge-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-v3", ++ "typename": "Skylake-Server-v3-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-v2", ++ "typename": "Skylake-Server-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-v1", ++ "typename": "Skylake-Server-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-noTSX-IBRS", ++ "typename": "Skylake-Server-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "alias-of": "Skylake-Server-v3", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-IBRS", ++ "typename": "Skylake-Server-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "alias-of": "Skylake-Server-v2", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server", ++ "typename": "Skylake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "alias-of": "Skylake-Server-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-v3", ++ "typename": "Skylake-Client-v3-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-v2", ++ "typename": "Skylake-Client-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-v1", ++ "typename": "Skylake-Client-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-noTSX-IBRS", ++ "typename": "Skylake-Client-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid" ++ ], ++ "alias-of": "Skylake-Client-v3", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-IBRS", ++ "typename": "Skylake-Client-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm" ++ ], ++ "alias-of": "Skylake-Client-v2", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client", ++ "typename": "Skylake-Client-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm" ++ ], ++ "alias-of": "Skylake-Client-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge-v2", ++ "typename": "SandyBridge-v2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge-v1", ++ "typename": "SandyBridge-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge-IBRS", ++ "typename": "SandyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "SandyBridge-v2", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge", ++ "typename": "SandyBridge-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "SandyBridge-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Penryn-v1", ++ "typename": "Penryn-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Penryn", ++ "typename": "Penryn-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "Penryn-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G5-v1", ++ "typename": "Opteron_G5-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "xop", ++ "fma4", ++ "tbm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G5", ++ "typename": "Opteron_G5-x86_64-cpu", ++ "unavailable-features": [ ++ "xop", ++ "fma4", ++ "tbm" ++ ], ++ "alias-of": "Opteron_G5-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G4-v1", ++ "typename": "Opteron_G4-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "xop", ++ "fma4" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G4", ++ "typename": "Opteron_G4-x86_64-cpu", ++ "unavailable-features": [ ++ "xop", ++ "fma4" ++ ], ++ "alias-of": "Opteron_G4-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G3-v1", ++ "typename": "Opteron_G3-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G3", ++ "typename": "Opteron_G3-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "Opteron_G3-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G2-v1", ++ "typename": "Opteron_G2-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G2", ++ "typename": "Opteron_G2-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "Opteron_G2-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G1-v1", ++ "typename": "Opteron_G1-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G1", ++ "typename": "Opteron_G1-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "Opteron_G1-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem-v2", ++ "typename": "Nehalem-v2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem-v1", ++ "typename": "Nehalem-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem-IBRS", ++ "typename": "Nehalem-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "Nehalem-v2", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem", ++ "typename": "Nehalem-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "Nehalem-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "KnightsMill-v1", ++ "typename": "KnightsMill-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "ss", ++ "erms", ++ "avx512f", ++ "avx512pf", ++ "avx512er", ++ "avx512cd", ++ "avx512-vpopcntdq", ++ "avx512-4vnniw", ++ "avx512-4fmaps", ++ "avx512f", ++ "avx512f", ++ "avx512f" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "KnightsMill", ++ "typename": "KnightsMill-x86_64-cpu", ++ "unavailable-features": [ ++ "ss", ++ "erms", ++ "avx512f", ++ "avx512pf", ++ "avx512er", ++ "avx512cd", ++ "avx512-vpopcntdq", ++ "avx512-4vnniw", ++ "avx512-4fmaps", ++ "avx512f", ++ "avx512f", ++ "avx512f" ++ ], ++ "alias-of": "KnightsMill-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge-v2", ++ "typename": "IvyBridge-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "erms" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge-v1", ++ "typename": "IvyBridge-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "erms" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge-IBRS", ++ "typename": "IvyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "erms" ++ ], ++ "alias-of": "IvyBridge-v2", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge", ++ "typename": "IvyBridge-x86_64-cpu", ++ "unavailable-features": [ ++ "erms" ++ ], ++ "alias-of": "IvyBridge-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Server-v2", ++ "typename": "Icelake-Server-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "la57", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Server-v1", ++ "typename": "Icelake-Server-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "la57", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Server-noTSX", ++ "typename": "Icelake-Server-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "la57", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "alias-of": "Icelake-Server-v2", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Server", ++ "typename": "Icelake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "la57", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "alias-of": "Icelake-Server-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Client-v2", ++ "typename": "Icelake-Client-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Client-v1", ++ "typename": "Icelake-Client-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Client-noTSX", ++ "typename": "Icelake-Client-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "pku" ++ ], ++ "alias-of": "Icelake-Client-v2", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Client", ++ "typename": "Icelake-Client-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "gfni", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "pku" ++ ], ++ "alias-of": "Icelake-Client-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-v4", ++ "typename": "Haswell-v4-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-v3", ++ "typename": "Haswell-v3-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-v2", ++ "typename": "Haswell-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-v1", ++ "typename": "Haswell-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX-IBRS", ++ "typename": "Haswell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid" ++ ], ++ "alias-of": "Haswell-v4", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX", ++ "typename": "Haswell-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid" ++ ], ++ "alias-of": "Haswell-v2", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-IBRS", ++ "typename": "Haswell-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm" ++ ], ++ "alias-of": "Haswell-v3", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell", ++ "typename": "Haswell-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm" ++ ], ++ "alias-of": "Haswell-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-v3", ++ "typename": "EPYC-v3-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-v2", ++ "typename": "EPYC-v2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-v1", ++ "typename": "EPYC-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-Rome-v1", ++ "typename": "EPYC-Rome-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-Rome", ++ "typename": "EPYC-Rome-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "EPYC-Rome-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-IBPB", ++ "typename": "EPYC-IBPB-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "EPYC-v2", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC", ++ "typename": "EPYC-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "EPYC-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Dhyana-v1", ++ "typename": "Dhyana-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Dhyana", ++ "typename": "Dhyana-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "Dhyana-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Denverton-v1", ++ "typename": "Denverton-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "erms", ++ "mpx", ++ "mpx", ++ "mpx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Denverton", ++ "typename": "Denverton-x86_64-cpu", ++ "unavailable-features": [ ++ "erms", ++ "mpx", ++ "mpx", ++ "mpx" ++ ], ++ "alias-of": "Denverton-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cooperlake-v1", ++ "typename": "Cooperlake-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "avx512-bf16", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku", ++ "ibrs-all" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cooperlake", ++ "typename": "Cooperlake-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "avx512-bf16", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku", ++ "ibrs-all" ++ ], ++ "alias-of": "Cooperlake-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Conroe-v1", ++ "typename": "Conroe-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Conroe", ++ "typename": "Conroe-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "Conroe-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cascadelake-Server-v3", ++ "typename": "Cascadelake-Server-v3-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku", ++ "ibrs-all" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cascadelake-Server-v2", ++ "typename": "Cascadelake-Server-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku", ++ "ibrs-all" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cascadelake-Server-v1", ++ "typename": "Cascadelake-Server-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cascadelake-Server-noTSX", ++ "typename": "Cascadelake-Server-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku", ++ "ibrs-all" ++ ], ++ "alias-of": "Cascadelake-Server-v3", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cascadelake-Server", ++ "typename": "Cascadelake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "alias-of": "Cascadelake-Server-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-v4", ++ "typename": "Broadwell-v4-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-v3", ++ "typename": "Broadwell-v3-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-v2", ++ "typename": "Broadwell-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-v1", ++ "typename": "Broadwell-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX-IBRS", ++ "typename": "Broadwell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid" ++ ], ++ "alias-of": "Broadwell-v4", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX", ++ "typename": "Broadwell-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "erms", ++ "invpcid" ++ ], ++ "alias-of": "Broadwell-v2", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-IBRS", ++ "typename": "Broadwell-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm" ++ ], ++ "alias-of": "Broadwell-v3", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell", ++ "typename": "Broadwell-x86_64-cpu", ++ "unavailable-features": [ ++ "pcid", ++ "hle", ++ "erms", ++ "invpcid", ++ "rtm" ++ ], ++ "alias-of": "Broadwell-v1", ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "486-v1", ++ "typename": "486-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "486", ++ "typename": "486-x86_64-cpu", ++ "unavailable-features": [], ++ "alias-of": "486-v1", ++ "static": false, ++ "migration-safe": true ++ } ++ ], ++ "id": "definitions" ++} +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.sig b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.sig +new file mode 100644 +index 0000000000..cf54739de9 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.sig +@@ -0,0 +1,4 @@ ++830f10 ++family: 23 (0x17) ++model: 49 (0x31) ++stepping: 0 (0x00) +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.xml +new file mode 100644 +index 0000000000..d6753065b9 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core.xml +@@ -0,0 +1,66 @@ ++<!-- AMD EPYC 7502 32-Core Processor --> ++<cpudata arch='x86'> ++ <cpuid eax_in='0x00000000' ecx_in='0x00' eax='0x00000010' ebx='0x68747541' ecx='0x444d4163' edx='0x69746e65'/> ++ <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00830f10' ebx='0x31400800' ecx='0x7ed8320b' edx='0x178bfbff'/> ++ <cpuid eax_in='0x00000002' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000003' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000005' ecx_in='0x00' eax='0x00000040' ebx='0x00000040' ecx='0x00000003' edx='0x00000011'/> ++ <cpuid eax_in='0x00000006' ecx_in='0x00' eax='0x00000004' ebx='0x00000000' ecx='0x00000001' edx='0x00000000'/> ++ <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x219c91a9' ecx='0x00400004' edx='0x00000000'/> ++ <cpuid eax_in='0x00000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000009' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000b' ecx_in='0x00' eax='0x00000001' ebx='0x00000002' ecx='0x00000100' edx='0x00000031'/> ++ <cpuid eax_in='0x0000000b' ecx_in='0x01' eax='0x00000007' ebx='0x00000040' ecx='0x00000201' edx='0x00000031'/> ++ <cpuid eax_in='0x0000000c' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000d' ecx_in='0x00' eax='0x00000207' ebx='0x00000340' ecx='0x00000380' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x0000000f' ebx='0x00000340' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000d' ecx_in='0x02' eax='0x00000100' ebx='0x00000240' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000d' ecx_in='0x09' eax='0x00000040' ebx='0x00000340' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000e' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000f' ecx_in='0x00' eax='0x00000000' ebx='0x000000ff' ecx='0x00000000' edx='0x00000002'/> ++ <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000000' ebx='0x00000040' ecx='0x000000ff' edx='0x00000007'/> ++ <cpuid eax_in='0x00000010' ecx_in='0x00' eax='0x00000000' ebx='0x00000002' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000010' ecx_in='0x01' eax='0x0000000f' ebx='0x00000000' ecx='0x00000004' edx='0x0000000f'/> ++ <cpuid eax_in='0x20000000' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000000' ecx_in='0x00' eax='0x80000020' ebx='0x68747541' ecx='0x444d4163' edx='0x69746e65'/> ++ <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00830f10' ebx='0x40000000' ecx='0x75c237ff' edx='0x2fd3fbff'/> ++ <cpuid eax_in='0x80000002' ecx_in='0x00' eax='0x20444d41' ebx='0x43595045' ecx='0x30353720' edx='0x32332032'/> ++ <cpuid eax_in='0x80000003' ecx_in='0x00' eax='0x726f432d' ebx='0x72502065' ecx='0x7365636f' edx='0x20726f73'/> ++ <cpuid eax_in='0x80000004' ecx_in='0x00' eax='0x20202020' ebx='0x20202020' ecx='0x20202020' edx='0x00202020'/> ++ <cpuid eax_in='0x80000005' ecx_in='0x00' eax='0xff40ff40' ebx='0xff40ff40' ecx='0x20080140' edx='0x20080140'/> ++ <cpuid eax_in='0x80000006' ecx_in='0x00' eax='0x48006400' ebx='0x68006400' ecx='0x02006140' edx='0x04009140'/> ++ <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x0000001b' ecx='0x00000000' edx='0x00006799'/> ++ <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00003030' ebx='0x018cf757' ecx='0x0000703f' edx='0x00010000'/> ++ <cpuid eax_in='0x80000009' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000001' ebx='0x00008000' ecx='0x00000000' edx='0x0013bcff'/> ++ <cpuid eax_in='0x8000000b' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000000c' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000000d' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000000e' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000000f' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000010' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000011' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000012' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000013' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000014' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000015' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000016' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000017' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000018' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000019' ecx_in='0x00' eax='0xf040f040' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000001a' ecx_in='0x00' eax='0x00000006' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000001b' ecx_in='0x00' eax='0x000003ff' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000001c' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000001d' ecx_in='0x00' eax='0x00004121' ebx='0x01c0003f' ecx='0x0000003f' edx='0x00000000'/> ++ <cpuid eax_in='0x8000001d' ecx_in='0x01' eax='0x00004122' ebx='0x01c0003f' ecx='0x0000003f' edx='0x00000000'/> ++ <cpuid eax_in='0x8000001d' ecx_in='0x02' eax='0x00004143' ebx='0x01c0003f' ecx='0x000003ff' edx='0x00000002'/> ++ <cpuid eax_in='0x8000001d' ecx_in='0x03' eax='0x0001c163' ebx='0x03c0003f' ecx='0x00003fff' edx='0x00000001'/> ++ <cpuid eax_in='0x8000001e' ecx_in='0x00' eax='0x00000031' ebx='0x00000118' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000001f' ecx_in='0x00' eax='0x0001000f' ebx='0x0000016f' ecx='0x000001fd' edx='0x00000001'/> ++ <cpuid eax_in='0x80000020' ecx_in='0x00' eax='0x00000000' ebx='0x00000002' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000020' ecx_in='0x01' eax='0x0000000b' ebx='0x00000000' ecx='0x00000000' edx='0x0000000f'/> ++ <cpuid eax_in='0x80860000' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0xc0000000' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <msr index='0x10a' edx='0x00000000' eax='0x00000069'/> ++</cpudata> +-- +2.29.2 + diff --git a/SOURCES/libvirt-Allow-NUMA-nodes-without-vCPUs.patch b/SOURCES/libvirt-Allow-NUMA-nodes-without-vCPUs.patch new file mode 100644 index 0000000..37df946 --- /dev/null +++ b/SOURCES/libvirt-Allow-NUMA-nodes-without-vCPUs.patch @@ -0,0 +1,456 @@ +From 5f6723e71e3765d1d43bfa9ba1c66e0e05e11a48 Mon Sep 17 00:00:00 2001 +Message-Id: <5f6723e71e3765d1d43bfa9ba1c66e0e05e11a48@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Mon, 9 Nov 2020 17:22:32 +0100 +Subject: [PATCH] Allow NUMA nodes without vCPUs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +QEMU allows creating NUMA nodes that have memory only. +These are somehow important for HMAT. + +With check done in qemuValidateDomainDef() for QEMU 2.7 or newer +(checked via QEMU_CAPS_NUMA), we can be sure that the vCPUs are +fully assigned to NUMA nodes in domain XML. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit a26f61ee0cffa421b87ef568002b684dd8025432) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Conflicts: +- src/qemu/qemu_validate.c: This file doesn't exist in downstream +yet, so I've moved the change that original patch would do to +qemu_domain.c where the validator lives. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <365508c75e579e9037ad555d6c372068ccd50c95.1604938867.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + docs/formatdomain.html.in | 2 + + docs/schemas/cputypes.rng | 8 ++- + src/conf/numa_conf.c | 59 ++++++++++--------- + src/libxl/xen_xl.c | 10 ++-- + src/qemu/qemu_command.c | 26 ++++---- + src/qemu/qemu_domain.c | 22 +++---- + tests/qemuxml2argvdata/numatune-no-vcpu.args | 33 +++++++++++ + tests/qemuxml2argvdata/numatune-no-vcpu.xml | 42 +++++++++++++ + tests/qemuxml2argvtest.c | 1 + + tests/qemuxml2xmloutdata/numatune-no-vcpu.xml | 1 + + tests/qemuxml2xmltest.c | 1 + + 11 files changed, 149 insertions(+), 56 deletions(-) + create mode 100644 tests/qemuxml2argvdata/numatune-no-vcpu.args + create mode 100644 tests/qemuxml2argvdata/numatune-no-vcpu.xml + create mode 120000 tests/qemuxml2xmloutdata/numatune-no-vcpu.xml + +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index 76799f5ffc..4b8d312596 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -1783,6 +1783,8 @@ + <code>cpus</code> specifies the CPU or range of CPUs that are + part of the node. <code>memory</code> specifies the node memory + in kibibytes (i.e. blocks of 1024 bytes). ++ <span class="since">Since 6.6.0</span> the <code>cpus</code> attribute ++ is optional and if omitted a CPU-less NUMA node is created. + <span class="since">Since 1.2.11</span> one can use an additional <a + href="#elementsMemoryAllocation"><code>unit</code></a> attribute to + define units in which <code>memory</code> is specified. +diff --git a/docs/schemas/cputypes.rng b/docs/schemas/cputypes.rng +index e2744acad3..a1682a1003 100644 +--- a/docs/schemas/cputypes.rng ++++ b/docs/schemas/cputypes.rng +@@ -115,9 +115,11 @@ + <ref name="unsignedInt"/> + </attribute> + </optional> +- <attribute name="cpus"> +- <ref name="cpuset"/> +- </attribute> ++ <optional> ++ <attribute name="cpus"> ++ <ref name="cpuset"/> ++ </attribute> ++ </optional> + <attribute name="memory"> + <ref name="memoryKB"/> + </attribute> +diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c +index c9cc8ac22e..a805336d16 100644 +--- a/src/conf/numa_conf.c ++++ b/src/conf/numa_conf.c +@@ -889,32 +889,28 @@ virDomainNumaDefParseXML(virDomainNumaPtr def, + } + VIR_FREE(tmp); + +- if (def->mem_nodes[cur_cell].cpumask) { ++ if (def->mem_nodes[cur_cell].mem) { + virReportError(VIR_ERR_XML_ERROR, + _("Duplicate NUMA cell info for cell id '%u'"), + cur_cell); + goto cleanup; + } + +- if (!(tmp = virXMLPropString(nodes[i], "cpus"))) { +- virReportError(VIR_ERR_XML_ERROR, "%s", +- _("Missing 'cpus' attribute in NUMA cell")); +- goto cleanup; +- } ++ if ((tmp = virXMLPropString(nodes[i], "cpus"))) { ++ g_autoptr(virBitmap) cpumask = NULL; + +- if (virBitmapParse(tmp, &def->mem_nodes[cur_cell].cpumask, +- VIR_DOMAIN_CPUMASK_LEN) < 0) +- goto cleanup; ++ if (virBitmapParse(tmp, &cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0) ++ goto cleanup; + +- if (virBitmapIsAllClear(def->mem_nodes[cur_cell].cpumask)) { +- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, +- _("NUMA cell %d has no vCPUs assigned"), cur_cell); +- goto cleanup; ++ if (!virBitmapIsAllClear(cpumask)) ++ def->mem_nodes[cur_cell].cpumask = g_steal_pointer(&cpumask); ++ VIR_FREE(tmp); + } +- VIR_FREE(tmp); + + for (j = 0; j < n; j++) { +- if (j == cur_cell || !def->mem_nodes[j].cpumask) ++ if (j == cur_cell || ++ !def->mem_nodes[j].cpumask || ++ !def->mem_nodes[cur_cell].cpumask) + continue; + + if (virBitmapOverlaps(def->mem_nodes[j].cpumask, +@@ -976,7 +972,6 @@ virDomainNumaDefFormatXML(virBufferPtr buf, + { + virDomainMemoryAccess memAccess; + virTristateBool discard; +- char *cpustr; + size_t ncells = virDomainNumaGetNodeCount(def); + size_t i; + +@@ -986,17 +981,22 @@ virDomainNumaDefFormatXML(virBufferPtr buf, + virBufferAddLit(buf, "<numa>\n"); + virBufferAdjustIndent(buf, 2); + for (i = 0; i < ncells; i++) { ++ virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(def, i); + int ndistances; + + memAccess = virDomainNumaGetNodeMemoryAccessMode(def, i); + discard = virDomainNumaGetNodeDiscard(def, i); + +- if (!(cpustr = virBitmapFormat(virDomainNumaGetNodeCpumask(def, i)))) +- return -1; +- + virBufferAddLit(buf, "<cell"); + virBufferAsprintf(buf, " id='%zu'", i); +- virBufferAsprintf(buf, " cpus='%s'", cpustr); ++ ++ if (cpumask) { ++ g_autofree char *cpustr = virBitmapFormat(cpumask); ++ ++ if (!cpustr) ++ return -1; ++ virBufferAsprintf(buf, " cpus='%s'", cpustr); ++ } + virBufferAsprintf(buf, " memory='%llu'", + virDomainNumaGetNodeMemorySize(def, i)); + virBufferAddLit(buf, " unit='KiB'"); +@@ -1032,8 +1032,6 @@ virDomainNumaDefFormatXML(virBufferPtr buf, + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</cell>\n"); + } +- +- VIR_FREE(cpustr); + } + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</numa>\n"); +@@ -1048,8 +1046,12 @@ virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa) + size_t i; + unsigned int ret = 0; + +- for (i = 0; i < numa->nmem_nodes; i++) +- ret += virBitmapCountBits(virDomainNumaGetNodeCpumask(numa, i)); ++ for (i = 0; i < numa->nmem_nodes; i++) { ++ virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(numa, i); ++ ++ if (cpumask) ++ ret += virBitmapCountBits(cpumask); ++ } + + return ret; + } +@@ -1061,11 +1063,14 @@ virDomainNumaGetMaxCPUID(virDomainNumaPtr numa) + unsigned int ret = 0; + + for (i = 0; i < numa->nmem_nodes; i++) { ++ virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(numa, i); + int bit; + +- bit = virBitmapLastSetBit(virDomainNumaGetNodeCpumask(numa, i)); +- if (bit > ret) +- ret = bit; ++ if (cpumask) { ++ bit = virBitmapLastSetBit(cpumask); ++ if (bit > ret) ++ ret = bit; ++ } + } + + return ret; +diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c +index edea30a86a..752fa925ec 100644 +--- a/src/libxl/xen_xl.c ++++ b/src/libxl/xen_xl.c +@@ -1443,19 +1443,21 @@ xenFormatXLVnuma(virConfValuePtr list, + { + int ret = -1; + size_t i; +- + virBuffer buf = VIR_BUFFER_INITIALIZER; + virConfValuePtr numaVnode, tmp; +- ++ virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(numa, node); + size_t nodeSize = virDomainNumaGetNodeMemorySize(numa, node) / 1024; +- char *nodeVcpus = virBitmapFormat(virDomainNumaGetNodeCpumask(numa, node)); ++ g_autofree char *nodeVcpus = NULL; + +- if (VIR_ALLOC(numaVnode) < 0) ++ if (!cpumask || ++ VIR_ALLOC(numaVnode) < 0) + goto cleanup; + + numaVnode->type = VIR_CONF_LIST; + numaVnode->list = NULL; + ++ nodeVcpus = virBitmapFormat(cpumask); ++ + /* pnode */ + virBufferAsprintf(&buf, "pnode=%zu", node); + xenFormatXLVnode(numaVnode, &buf); +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 1a573c2817..ac63d18a42 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -7364,8 +7364,6 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg, + size_t i, j; + virQEMUCapsPtr qemuCaps = priv->qemuCaps; + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; +- char *cpumask = NULL; +- char *tmpmask = NULL; + char *next = NULL; + virBufferPtr nodeBackends = NULL; + bool needBackend = false; +@@ -7400,9 +7398,7 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg, + goto cleanup; + + for (i = 0; i < ncells; i++) { +- VIR_FREE(cpumask); +- if (!(cpumask = virBitmapFormat(virDomainNumaGetNodeCpumask(def->numa, i)))) +- goto cleanup; ++ virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(def->numa, i); + + if (needBackend) { + virCommandAddArg(cmd, "-object"); +@@ -7412,11 +7408,19 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg, + virCommandAddArg(cmd, "-numa"); + virBufferAsprintf(&buf, "node,nodeid=%zu", i); + +- for (tmpmask = cpumask; tmpmask; tmpmask = next) { +- if ((next = strchr(tmpmask, ','))) +- *(next++) = '\0'; +- virBufferAddLit(&buf, ",cpus="); +- virBufferAdd(&buf, tmpmask, -1); ++ if (cpumask) { ++ g_autofree char *cpumaskStr = NULL; ++ char *tmpmask; ++ ++ if (!(cpumaskStr = virBitmapFormat(cpumask))) ++ goto cleanup; ++ ++ for (tmpmask = cpumaskStr; tmpmask; tmpmask = next) { ++ if ((next = strchr(tmpmask, ','))) ++ *(next++) = '\0'; ++ virBufferAddLit(&buf, ",cpus="); ++ virBufferAdd(&buf, tmpmask, -1); ++ } + } + + if (needBackend) +@@ -7447,8 +7451,6 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg, + ret = 0; + + cleanup: +- VIR_FREE(cpumask); +- + if (nodeBackends) { + for (i = 0; i < ncells; i++) + virBufferFreeAndReset(&nodeBackends[i]); +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 35b536868a..be25790f12 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -5373,7 +5373,7 @@ qemuDomainDefValidateNuma(const virDomainDef *def, + } + + for (i = 0; i < ncells; i++) { +- g_autofree char * cpumask = NULL; ++ virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(def->numa, i); + + if (!hasMemoryCap && + virDomainNumaGetNodeMemoryAccessMode(def->numa, i)) { +@@ -5383,17 +5383,19 @@ qemuDomainDefValidateNuma(const virDomainDef *def, + return -1; + } + +- if (!(cpumask = virBitmapFormat(virDomainNumaGetNodeCpumask(def->numa, i)))) +- return -1; ++ if (cpumask) { ++ g_autofree char * cpumaskStr = NULL; ++ if (!(cpumaskStr = virBitmapFormat(cpumask))) ++ return -1; + +- if (strchr(cpumask, ',') && +- !virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA)) { +- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", +- _("disjoint NUMA cpu ranges are not supported " +- "with this QEMU")); +- return -1; ++ if (strchr(cpumaskStr, ',') && ++ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("disjoint NUMA cpu ranges are not supported " ++ "with this QEMU")); ++ return -1; ++ } + } +- + } + + if (virDomainNumaNodesDistancesAreBeingSet(def->numa) && +diff --git a/tests/qemuxml2argvdata/numatune-no-vcpu.args b/tests/qemuxml2argvdata/numatune-no-vcpu.args +new file mode 100644 +index 0000000000..a1f1ee044e +--- /dev/null ++++ b/tests/qemuxml2argvdata/numatune-no-vcpu.args +@@ -0,0 +1,33 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/tmp/lib/domain--1-QEMUGuest \ ++USER=test \ ++LOGNAME=test \ ++XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest/.local/share \ ++XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest/.cache \ ++XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest/.config \ ++QEMU_AUDIO_DRV=none \ ++/usr/bin/qemu-system-x86_64 \ ++-name QEMUGuest \ ++-S \ ++-machine pc,accel=tcg,usb=off,dump-guest-core=off \ ++-m 12288 \ ++-realtime mlock=off \ ++-smp 12,sockets=12,cores=1,threads=1 \ ++-numa node,nodeid=0,cpus=0-3,mem=2048 \ ++-numa node,nodeid=1,cpus=4-7,mem=2048 \ ++-numa node,nodeid=2,cpus=8-11,mem=2048 \ ++-numa node,nodeid=3,mem=2048 \ ++-numa node,nodeid=4,mem=2048 \ ++-numa node,nodeid=5,mem=2048 \ ++-uuid c7a5fdb2-cdaf-9455-926a-d65c16db1809 \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest/monitor.sock,\ ++server,nowait \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-usb \ ++-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 +diff --git a/tests/qemuxml2argvdata/numatune-no-vcpu.xml b/tests/qemuxml2argvdata/numatune-no-vcpu.xml +new file mode 100644 +index 0000000000..f25a07d7ed +--- /dev/null ++++ b/tests/qemuxml2argvdata/numatune-no-vcpu.xml +@@ -0,0 +1,42 @@ ++<domain type='qemu'> ++ <name>QEMUGuest</name> ++ <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid> ++ <memory unit='KiB'>12582912</memory> ++ <currentMemory unit='KiB'>12582912</currentMemory> ++ <vcpu placement='static'>12</vcpu> ++ <os> ++ <type arch='x86_64' machine='pc'>hvm</type> ++ <boot dev='hd'/> ++ </os> ++ <features> ++ <acpi/> ++ <apic/> ++ <pae/> ++ </features> ++ <cpu> ++ <numa> ++ <cell id='0' cpus='0-3' memory='2097152' unit='KiB'/> ++ <cell id='1' cpus='4-7' memory='2097152' unit='KiB'/> ++ <cell id='2' cpus='8-11' memory='2097152' unit='KiB'/> ++ <cell id='3' memory='2097152' unit='KiB'/> ++ <cell id='4' memory='2097152' unit='KiB'/> ++ <cell id='5' memory='2097152' unit='KiB'/> ++ </numa> ++ </cpu> ++ <clock offset='utc'/> ++ <on_poweroff>destroy</on_poweroff> ++ <on_reboot>restart</on_reboot> ++ <on_crash>restart</on_crash> ++ <devices> ++ <emulator>/usr/bin/qemu-system-x86_64</emulator> ++ <controller type='usb' index='0'> ++ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> ++ </controller> ++ <controller type='pci' index='0' model='pci-root'/> ++ <input type='mouse' bus='ps2'/> ++ <input type='keyboard' bus='ps2'/> ++ <memballoon model='virtio'> ++ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> ++ </memballoon> ++ </devices> ++</domain> +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index ff92af606d..49699e495d 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -1812,6 +1812,7 @@ mymain(void) + DO_TEST_PARSE_ERROR("numatune-memnode-no-memory", NONE); + + DO_TEST("numatune-distances", QEMU_CAPS_NUMA, QEMU_CAPS_NUMA_DIST); ++ DO_TEST("numatune-no-vcpu", NONE); + + DO_TEST("numatune-auto-nodeset-invalid", NONE); + DO_TEST("numatune-auto-prefer", QEMU_CAPS_OBJECT_MEMORY_RAM, +diff --git a/tests/qemuxml2xmloutdata/numatune-no-vcpu.xml b/tests/qemuxml2xmloutdata/numatune-no-vcpu.xml +new file mode 120000 +index 0000000000..f213032685 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/numatune-no-vcpu.xml +@@ -0,0 +1 @@ ++../qemuxml2argvdata/numatune-no-vcpu.xml +\ No newline at end of file +diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c +index 6c3f5c4a9e..1ddeba30f0 100644 +--- a/tests/qemuxml2xmltest.c ++++ b/tests/qemuxml2xmltest.c +@@ -1105,6 +1105,7 @@ mymain(void) + DO_TEST("numatune-memnode", QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_FILE); + DO_TEST("numatune-memnode-no-memory", QEMU_CAPS_OBJECT_MEMORY_FILE); + DO_TEST("numatune-distances", QEMU_CAPS_NUMA, QEMU_CAPS_NUMA_DIST); ++ DO_TEST("numatune-no-vcpu", QEMU_CAPS_NUMA); + + DO_TEST("bios-nvram", NONE); + DO_TEST("bios-nvram-os-interleave", NONE); +-- +2.29.2 + diff --git a/SOURCES/libvirt-RNG-Allow-interleaving-of-domain-cpu-numa-cell-children.patch b/SOURCES/libvirt-RNG-Allow-interleaving-of-domain-cpu-numa-cell-children.patch new file mode 100644 index 0000000..27fb4b4 --- /dev/null +++ b/SOURCES/libvirt-RNG-Allow-interleaving-of-domain-cpu-numa-cell-children.patch @@ -0,0 +1,63 @@ +From e37b1531942872a229b9f45524ea4679f3b1e8d6 Mon Sep 17 00:00:00 2001 +Message-Id: <e37b1531942872a229b9f45524ea4679f3b1e8d6@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Mon, 9 Nov 2020 17:22:33 +0100 +Subject: [PATCH] RNG: Allow interleaving of /domain/cpu/numa/cell children +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +So far, the <cell/> element can have two types of children +elements: <distances/> and <cache/> (which can be repeated more +times). However, there is no reason to require specific order in +input XML. Allow elements to be interleaved. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +(cherry picked from commit fd2ad818b29ca56904dd228f0774f553f99c1157) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <48b8e99ea6fbc6bcab0f7b3d17e7824ef1b232e2.1604938847.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + docs/schemas/cputypes.rng | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +diff --git a/docs/schemas/cputypes.rng b/docs/schemas/cputypes.rng +index ba30dbf9ff..a1cae23161 100644 +--- a/docs/schemas/cputypes.rng ++++ b/docs/schemas/cputypes.rng +@@ -146,16 +146,18 @@ + <ref name="virYesNo"/> + </attribute> + </optional> +- <optional> +- <element name="distances"> +- <oneOrMore> +- <ref name="numaDistance"/> +- </oneOrMore> +- </element> +- </optional> +- <zeroOrMore> +- <ref name="numaCache"/> +- </zeroOrMore> ++ <interleave> ++ <optional> ++ <element name="distances"> ++ <oneOrMore> ++ <ref name="numaDistance"/> ++ </oneOrMore> ++ </element> ++ </optional> ++ <zeroOrMore> ++ <ref name="numaCache"/> ++ </zeroOrMore> ++ </interleave> + </element> + </define> + +-- +2.29.2 + diff --git a/SOURCES/libvirt-cgroup-use-virCgroupSetCpuShares-instead-of-virCgroupSetupCpuShares.patch b/SOURCES/libvirt-cgroup-use-virCgroupSetCpuShares-instead-of-virCgroupSetupCpuShares.patch new file mode 100644 index 0000000..9eec89b --- /dev/null +++ b/SOURCES/libvirt-cgroup-use-virCgroupSetCpuShares-instead-of-virCgroupSetupCpuShares.patch @@ -0,0 +1,146 @@ +From 8d08db00d403ddd17cb51d972842c6d13a122d57 Mon Sep 17 00:00:00 2001 +Message-Id: <8d08db00d403ddd17cb51d972842c6d13a122d57@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Thu, 4 Mar 2021 12:57:58 +0100 +Subject: [PATCH] cgroup: use virCgroupSetCpuShares instead of + virCgroupSetupCpuShares +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Now that we enforce the cpu.shares range kernel will no longer silently +change the value that libvirt configures so there is no need to read +the value back to get the actual configuration. + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit e95489d813cb7cc68b02905ce3ec059bc395b465) + +Conflicts: + src/lxc/lxc_cgroup.c + src/lxc/lxc_driver.c + src/qemu/qemu_cgroup.c + src/qemu/qemu_driver.c + - downstream doesn't have virCgroupSetupCpuShares() function + so we just remove usage of virCgroupGetCpuShares() + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <a7f8e3c0ce4bc22eccbaa25a434d5e72e74d8a65.1614858616.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/lxc/lxc_cgroup.c | 5 ----- + src/lxc/lxc_driver.c | 6 +----- + src/qemu/qemu_cgroup.c | 20 -------------------- + src/qemu/qemu_driver.c | 8 ++------ + 4 files changed, 3 insertions(+), 36 deletions(-) + +diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c +index 7f3701593a..f785f50754 100644 +--- a/src/lxc/lxc_cgroup.c ++++ b/src/lxc/lxc_cgroup.c +@@ -38,13 +38,8 @@ static int virLXCCgroupSetupCpuTune(virDomainDefPtr def, + virCgroupPtr cgroup) + { + if (def->cputune.sharesSpecified) { +- unsigned long long val; + if (virCgroupSetCpuShares(cgroup, def->cputune.shares) < 0) + return -1; +- +- if (virCgroupGetCpuShares(cgroup, &val) < 0) +- return -1; +- def->cputune.shares = val; + } + + if (def->cputune.quota != 0 && +diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c +index a8c93dd228..853ddac8b9 100644 +--- a/src/lxc/lxc_driver.c ++++ b/src/lxc/lxc_driver.c +@@ -1909,14 +1909,10 @@ lxcDomainSetSchedulerParametersFlags(virDomainPtr dom, + + if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_CPU_SHARES)) { + if (def) { +- unsigned long long val; + if (virCgroupSetCpuShares(priv->cgroup, params[i].value.ul) < 0) + goto endjob; + +- if (virCgroupGetCpuShares(priv->cgroup, &val) < 0) +- goto endjob; +- +- def->cputune.shares = val; ++ def->cputune.shares = params[i].value.ul; + def->cputune.sharesSpecified = true; + } + +diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c +index 3a62b4ac15..95ea5bed74 100644 +--- a/src/qemu/qemu_cgroup.c ++++ b/src/qemu/qemu_cgroup.c +@@ -933,10 +933,6 @@ static int + qemuSetupCpuCgroup(virDomainObjPtr vm) + { + qemuDomainObjPrivatePtr priv = vm->privateData; +- virObjectEventPtr event = NULL; +- virTypedParameterPtr eventParams = NULL; +- int eventNparams = 0; +- int eventMaxparams = 0; + + if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) { + if (vm->def->cputune.sharesSpecified) { +@@ -949,24 +945,8 @@ qemuSetupCpuCgroup(virDomainObjPtr vm) + } + + if (vm->def->cputune.sharesSpecified) { +- unsigned long long val; + if (virCgroupSetCpuShares(priv->cgroup, vm->def->cputune.shares) < 0) + return -1; +- +- if (virCgroupGetCpuShares(priv->cgroup, &val) < 0) +- return -1; +- if (vm->def->cputune.shares != val) { +- vm->def->cputune.shares = val; +- if (virTypedParamsAddULLong(&eventParams, &eventNparams, +- &eventMaxparams, +- VIR_DOMAIN_TUNABLE_CPU_CPU_SHARES, +- val) < 0) +- return -1; +- +- event = virDomainEventTunableNewFromObj(vm, eventParams, eventNparams); +- } +- +- virObjectEventStateQueue(priv->driver->domainEventState, event); + } + + return 0; +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index a1103a96dd..3914d3ff68 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -10625,20 +10625,16 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, + + if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_CPU_SHARES)) { + if (def) { +- unsigned long long val; + if (virCgroupSetCpuShares(priv->cgroup, value_ul) < 0) + goto endjob; + +- if (virCgroupGetCpuShares(priv->cgroup, &val) < 0) +- goto endjob; +- +- def->cputune.shares = val; ++ def->cputune.shares = value_ul; + def->cputune.sharesSpecified = true; + + if (virTypedParamsAddULLong(&eventParams, &eventNparams, + &eventMaxNparams, + VIR_DOMAIN_TUNABLE_CPU_CPU_SHARES, +- val) < 0) ++ value_ul) < 0) + goto endjob; + } + +-- +2.30.0 + diff --git a/SOURCES/libvirt-check-for-NULL-before-calling-g_regex_unref.patch b/SOURCES/libvirt-check-for-NULL-before-calling-g_regex_unref.patch new file mode 100644 index 0000000..a0c6d04 --- /dev/null +++ b/SOURCES/libvirt-check-for-NULL-before-calling-g_regex_unref.patch @@ -0,0 +1,77 @@ +From 5fe7795d5fa5061f0ba615472f9351f9d29abf48 Mon Sep 17 00:00:00 2001 +Message-Id: <5fe7795d5fa5061f0ba615472f9351f9d29abf48@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com> +Date: Fri, 2 Oct 2020 13:44:44 +0200 +Subject: [PATCH] check for NULL before calling g_regex_unref +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +g_regex_unref reports an error if called with a NULL argument. + +We have two cases in the code where we (possibly) call it on a NULL +argument. The interesting one is in virDomainQemuMonitorEventCleanup. + +Based on VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX, we unref +data->regex, which has two problems: + +* On the client side, flags is -1 so the comparison is true even if no + regex was used, reproducible by: + $ virsh qemu-monitor-event --timeout 1 + which results in an ugly error: +(process:1289846): GLib-CRITICAL **: 14:58:42.631: g_regex_unref: assertion 'regex != NULL' failed +* On the server side, we only create the regex if both the flag and the + string are present, so it's possible to trigger this message by: + $ virsh qemu-monitor-event --regex --timeout 1 + +Use a non-NULL comparison instead of the flag to decide whether we need +to unref the regex. And add a non-NULL check to the unref in the +VirtualBox test too. + +Signed-off-by: Ján Tomko <jtomko@redhat.com> +Fixes: 71efb59a4de7c51b1bc889a316f1796ebf55738f +https://bugzilla.redhat.com/show_bug.cgi?id=1876907 +Reviewed-by: Peter Krempa <pkrempa@redhat.com> +Reviewed-by: Martin Kletzander <mkletzan@redhat.com> +(cherry picked from commit 92b252456ee6d6ffc6e39e62ce1ce6c50113e00e) + +https://bugzilla.redhat.com/show_bug.cgi?id=1861176 + +Signed-off-by: Ján Tomko <jtomko@redhat.com> +Message-Id: <7d3c84f6556d0d46ada037d5e56c831babba609f.1601639064.git.jtomko@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/conf/domain_event.c | 2 +- + tests/vboxsnapshotxmltest.c | 3 ++- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c +index 33fbf10406..d3acde0236 100644 +--- a/src/conf/domain_event.c ++++ b/src/conf/domain_event.c +@@ -2194,7 +2194,7 @@ virDomainQemuMonitorEventCleanup(void *opaque) + virDomainQemuMonitorEventData *data = opaque; + + VIR_FREE(data->event); +- if (data->flags & VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX) ++ if (data->regex) + g_regex_unref(data->regex); + if (data->freecb) + (data->freecb)(data->opaque); +diff --git a/tests/vboxsnapshotxmltest.c b/tests/vboxsnapshotxmltest.c +index d1a7522931..8577157020 100644 +--- a/tests/vboxsnapshotxmltest.c ++++ b/tests/vboxsnapshotxmltest.c +@@ -134,7 +134,8 @@ mymain(void) + DO_TEST("2disks-3snap-brother"); + + cleanup: +- g_regex_unref(testSnapshotXMLVariableLineRegex); ++ if (testSnapshotXMLVariableLineRegex) ++ g_regex_unref(testSnapshotXMLVariableLineRegex); + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + } + +-- +2.28.0 + diff --git a/SOURCES/libvirt-conf-Move-and-rename-virDomainParseScaledValue.patch b/SOURCES/libvirt-conf-Move-and-rename-virDomainParseScaledValue.patch new file mode 100644 index 0000000..52e7f0b --- /dev/null +++ b/SOURCES/libvirt-conf-Move-and-rename-virDomainParseScaledValue.patch @@ -0,0 +1,357 @@ +From 0cee78aa69f5e3317b5e4853454a108e597228e5 Mon Sep 17 00:00:00 2001 +Message-Id: <0cee78aa69f5e3317b5e4853454a108e597228e5@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Wed, 7 Oct 2020 18:45:33 +0200 +Subject: [PATCH] conf: Move and rename virDomainParseScaledValue() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is nothing domain specific about the function, thus it +should not have virDomain prefix. Also, the fact that it is a +static function makes it impossible to use from other files. +Move the function to virxml.c and drop the 'Domain' infix. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit 04bd77a19f8312493151ce377da40577b1470a0b) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Conflicts: +- src/conf/domain_conf.c: Some context mismatch, and some areas +the original commit changes don't exist in this old libvirt yet +or the calls are in other places because of refactors. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <26a847deef5941fd90f892cf5fe1443cf3fc90ca.1602087923.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/conf/domain_conf.c | 135 ++++++++++----------------------------- + src/libvirt_private.syms | 1 + + src/util/virxml.c | 72 +++++++++++++++++++++ + src/util/virxml.h | 8 +++ + 4 files changed, 114 insertions(+), 102 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 306926b64c..484f3b4352 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -10644,75 +10644,6 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, + goto cleanup; + } + +-/** +- * virDomainParseScaledValue: +- * @xpath: XPath to memory amount +- * @units_xpath: XPath to units attribute +- * @ctxt: XPath context +- * @val: scaled value is stored here +- * @scale: default scale for @val +- * @max: maximal @val allowed +- * @required: is the value required? +- * +- * Parse a value located at @xpath within @ctxt, and store the +- * result into @val. The value is scaled by units located at +- * @units_xpath (or the 'unit' attribute under @xpath if +- * @units_xpath is NULL). If units are not present, the default +- * @scale is used. If @required is set, then the value must +- * exist; otherwise, the value is optional. The resulting value +- * is in bytes. +- * +- * Returns 1 on success, +- * 0 if the value was not present and !@required, +- * -1 on failure after issuing error. +- */ +-static int +-virDomainParseScaledValue(const char *xpath, +- const char *units_xpath, +- xmlXPathContextPtr ctxt, +- unsigned long long *val, +- unsigned long long scale, +- unsigned long long max, +- bool required) +-{ +- unsigned long long bytes; +- g_autofree char *xpath_full = NULL; +- g_autofree char *unit = NULL; +- g_autofree char *bytes_str = NULL; +- +- *val = 0; +- xpath_full = g_strdup_printf("string(%s)", xpath); +- +- bytes_str = virXPathString(xpath_full, ctxt); +- if (!bytes_str) { +- if (!required) +- return 0; +- virReportError(VIR_ERR_XML_ERROR, +- _("missing element or attribute '%s'"), +- xpath); +- return -1; +- } +- VIR_FREE(xpath_full); +- +- if (virStrToLong_ullp(bytes_str, NULL, 10, &bytes) < 0) { +- virReportError(VIR_ERR_XML_ERROR, +- _("Invalid value '%s' for element or attribute '%s'"), +- bytes_str, xpath); +- return -1; +- } +- +- if (units_xpath) +- xpath_full = g_strdup_printf("string(%s)", units_xpath); +- else +- xpath_full = g_strdup_printf("string(%s/@unit)", xpath); +- unit = virXPathString(xpath_full, ctxt); +- +- if (virScaleInteger(&bytes, unit, scale, max) < 0) +- return -1; +- +- *val = bytes; +- return 1; +-} + + + /** +@@ -10749,8 +10680,8 @@ virDomainParseMemory(const char *xpath, + + max = virMemoryMaxValue(capped); + +- if (virDomainParseScaledValue(xpath, units_xpath, ctxt, +- &bytes, 1024, max, required) < 0) ++ if (virParseScaledValue(xpath, units_xpath, ctxt, ++ &bytes, 1024, max, required) < 0) + return -1; + + /* Yes, we really do use kibibytes for our internal sizing. */ +@@ -10792,9 +10723,9 @@ virDomainParseMemoryLimit(const char *xpath, + int ret; + unsigned long long bytes; + +- ret = virDomainParseScaledValue(xpath, units_xpath, ctxt, &bytes, 1024, +- VIR_DOMAIN_MEMORY_PARAM_UNLIMITED << 10, +- false); ++ ret = virParseScaledValue(xpath, units_xpath, ctxt, &bytes, 1024, ++ VIR_DOMAIN_MEMORY_PARAM_UNLIMITED << 10, ++ false); + + if (ret < 0) + return -1; +@@ -11125,9 +11056,9 @@ virDomainControllerDefParseXML(virDomainXMLOptionPtr xmlopt, + "have an address")); + goto error; + } +- if ((rc = virDomainParseScaledValue("./pcihole64", NULL, +- ctxt, &bytes, 1024, +- 1024ULL * ULONG_MAX, false)) < 0) ++ if ((rc = virParseScaledValue("./pcihole64", NULL, ++ ctxt, &bytes, 1024, ++ 1024ULL * ULONG_MAX, false)) < 0) + goto error; + + if (rc == 1) +@@ -11349,14 +11280,14 @@ virDomainFSDefParseXML(virDomainXMLOptionPtr xmlopt, + } + } + +- if (virDomainParseScaledValue("./space_hard_limit[1]", +- NULL, ctxt, &def->space_hard_limit, +- 1, ULLONG_MAX, false) < 0) ++ if (virParseScaledValue("./space_hard_limit[1]", ++ NULL, ctxt, &def->space_hard_limit, ++ 1, ULLONG_MAX, false) < 0) + goto error; + +- if (virDomainParseScaledValue("./space_soft_limit[1]", +- NULL, ctxt, &def->space_soft_limit, +- 1, ULLONG_MAX, false) < 0) ++ if (virParseScaledValue("./space_soft_limit[1]", ++ NULL, ctxt, &def->space_soft_limit, ++ 1, ULLONG_MAX, false) < 0) + goto error; + + cur = node->children; +@@ -15205,8 +15136,8 @@ virDomainShmemDefParseXML(virDomainXMLOptionPtr xmlopt, + goto cleanup; + } + +- if (virDomainParseScaledValue("./size[1]", NULL, ctxt, +- &def->size, 1, ULLONG_MAX, false) < 0) ++ if (virParseScaledValue("./size[1]", NULL, ctxt, ++ &def->size, 1, ULLONG_MAX, false) < 0) + goto cleanup; + + if ((server = virXPathNode("./server[1]", ctxt))) { +@@ -19603,9 +19534,9 @@ virDomainCachetuneDefParseCache(xmlXPathContextPtr ctxt, + return -1; + } + +- if (virDomainParseScaledValue("./@size", "./@unit", +- ctxt, &size, 1024, +- ULLONG_MAX, true) < 0) ++ if (virParseScaledValue("./@size", "./@unit", ++ ctxt, &size, 1024, ++ ULLONG_MAX, true) < 0) + return -1; + + if (virResctrlAllocSetCacheSize(alloc, level, type, cache, size) < 0) +@@ -20712,13 +20643,13 @@ virDomainDefParseXML(xmlDocPtr xml, + VIR_FREE(tmp); + } + +- if (virDomainParseScaledValue("./features/hpt/maxpagesize", +- NULL, +- ctxt, +- &def->hpt_maxpagesize, +- 1024, +- ULLONG_MAX, +- false) < 0) { ++ if (virParseScaledValue("./features/hpt/maxpagesize", ++ NULL, ++ ctxt, ++ &def->hpt_maxpagesize, ++ 1024, ++ ULLONG_MAX, ++ false) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + "%s", + _("Unable to parse HPT maxpagesize setting")); +@@ -20944,13 +20875,13 @@ virDomainDefParseXML(xmlDocPtr xml, + } + + if (def->features[VIR_DOMAIN_FEATURE_SMM] == VIR_TRISTATE_SWITCH_ON) { +- int rv = virDomainParseScaledValue("string(./features/smm/tseg)", +- "string(./features/smm/tseg/@unit)", +- ctxt, +- &def->tseg_size, +- 1024 * 1024, /* Defaults to mebibytes */ +- ULLONG_MAX, +- false); ++ int rv = virParseScaledValue("string(./features/smm/tseg)", ++ "string(./features/smm/tseg/@unit)", ++ ctxt, ++ &def->tseg_size, ++ 1024 * 1024, /* Defaults to mebibytes */ ++ ULLONG_MAX, ++ false); + if (rv < 0) + goto error; + def->tseg_specified = rv; +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 130828706a..acb25eb8c8 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -3442,6 +3442,7 @@ virVsockSetGuestCid; + + + # util/virxml.h ++virParseScaledValue; + virXMLCheckIllegalChars; + virXMLChildElementCount; + virXMLExtractNamespaceXML; +diff --git a/src/util/virxml.c b/src/util/virxml.c +index 0e66d1623b..bae2e6aca5 100644 +--- a/src/util/virxml.c ++++ b/src/util/virxml.c +@@ -33,6 +33,7 @@ + #include "viralloc.h" + #include "virfile.h" + #include "virstring.h" ++#include "virutil.h" + + #define VIR_FROM_THIS VIR_FROM_XML + +@@ -1433,3 +1434,74 @@ virXMLNamespaceRegister(xmlXPathContextPtr ctxt, + + return 0; + } ++ ++ ++/** ++ * virParseScaledValue: ++ * @xpath: XPath to memory amount ++ * @units_xpath: XPath to units attribute ++ * @ctxt: XPath context ++ * @val: scaled value is stored here ++ * @scale: default scale for @val ++ * @max: maximal @val allowed ++ * @required: is the value required? ++ * ++ * Parse a value located at @xpath within @ctxt, and store the ++ * result into @val. The value is scaled by units located at ++ * @units_xpath (or the 'unit' attribute under @xpath if ++ * @units_xpath is NULL). If units are not present, the default ++ * @scale is used. If @required is set, then the value must ++ * exist; otherwise, the value is optional. The resulting value ++ * is in bytes. ++ * ++ * Returns 1 on success, ++ * 0 if the value was not present and !@required, ++ * -1 on failure after issuing error. ++ */ ++int ++virParseScaledValue(const char *xpath, ++ const char *units_xpath, ++ xmlXPathContextPtr ctxt, ++ unsigned long long *val, ++ unsigned long long scale, ++ unsigned long long max, ++ bool required) ++{ ++ unsigned long long bytes; ++ g_autofree char *xpath_full = NULL; ++ g_autofree char *unit = NULL; ++ g_autofree char *bytes_str = NULL; ++ ++ *val = 0; ++ xpath_full = g_strdup_printf("string(%s)", xpath); ++ ++ bytes_str = virXPathString(xpath_full, ctxt); ++ if (!bytes_str) { ++ if (!required) ++ return 0; ++ virReportError(VIR_ERR_XML_ERROR, ++ _("missing element or attribute '%s'"), ++ xpath); ++ return -1; ++ } ++ VIR_FREE(xpath_full); ++ ++ if (virStrToLong_ullp(bytes_str, NULL, 10, &bytes) < 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("Invalid value '%s' for element or attribute '%s'"), ++ bytes_str, xpath); ++ return -1; ++ } ++ ++ if (units_xpath) ++ xpath_full = g_strdup_printf("string(%s)", units_xpath); ++ else ++ xpath_full = g_strdup_printf("string(%s/@unit)", xpath); ++ unit = virXPathString(xpath_full, ctxt); ++ ++ if (virScaleInteger(&bytes, unit, scale, max) < 0) ++ return -1; ++ ++ *val = bytes; ++ return 1; ++} +diff --git a/src/util/virxml.h b/src/util/virxml.h +index 26ab9f9c2d..39b261687a 100644 +--- a/src/util/virxml.h ++++ b/src/util/virxml.h +@@ -269,3 +269,11 @@ virXMLNamespaceFormatNS(virBufferPtr buf, + int + virXMLNamespaceRegister(xmlXPathContextPtr ctxt, + virXMLNamespace const *ns); ++ ++int virParseScaledValue(const char *xpath, ++ const char *units_xpath, ++ xmlXPathContextPtr ctxt, ++ unsigned long long *val, ++ unsigned long long scale, ++ unsigned long long max, ++ bool required); +-- +2.29.2 + diff --git a/SOURCES/libvirt-conf-Parse-and-format-HMAT.patch b/SOURCES/libvirt-conf-Parse-and-format-HMAT.patch new file mode 100644 index 0000000..6f3d8f6 --- /dev/null +++ b/SOURCES/libvirt-conf-Parse-and-format-HMAT.patch @@ -0,0 +1,877 @@ +From 17e9b949ec3876e74bcaa217810afbd46f297a65 Mon Sep 17 00:00:00 2001 +Message-Id: <17e9b949ec3876e74bcaa217810afbd46f297a65@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Wed, 7 Oct 2020 18:45:39 +0200 +Subject: [PATCH] conf: Parse and format HMAT +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +To cite ACPI specification: + + Heterogeneous Memory Attribute Table describes the memory + attributes, such as memory side cache attributes and bandwidth + and latency details, related to the System Physical Address + (SPA) Memory Ranges. The software is expected to use this + information as hint for optimization. + +According to our upstream discussion [1] this is exposed under +<numa/> as <cache/> under NUMA <cell/> and <latency> or +<bandwidth/> under numa/latencies. + +1: https://www.redhat.com/archives/libvir-list/2020-January/msg00422.html + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit a89bbbac86383a10be0cec5a93feb7ed820871eb) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Conflicts: +- src/conf/numa_conf.c: Context, because we're not using +VIR_XPATH_NODE_AUTORESTORE() everywhere in the old code. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <f5d9028ca8eff876c2bd471460629d0ef3b20630.1602087923.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + docs/formatdomain.html.in | 107 +++++++ + docs/schemas/cputypes.rng | 110 ++++++- + src/conf/numa_conf.c | 349 ++++++++++++++++++++- + src/conf/numa_conf.h | 33 ++ + src/libvirt_private.syms | 6 + + tests/qemuxml2argvdata/numatune-hmat.xml | 52 +++ + tests/qemuxml2xmloutdata/numatune-hmat.xml | 1 + + tests/qemuxml2xmltest.c | 1 + + 8 files changed, 644 insertions(+), 15 deletions(-) + create mode 100644 tests/qemuxml2argvdata/numatune-hmat.xml + create mode 120000 tests/qemuxml2xmloutdata/numatune-hmat.xml + +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index 4b8d312596..bec753e37f 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -1874,6 +1874,113 @@ + using 10 for local and 20 for remote distances. + </p> + ++ <h4><a id="hmat">ACPI Heterogeneous Memory Attribute Table</a></h4> ++ ++<pre> ++... ++<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> ++...</pre> ++ ++ <p> ++ <span class='since'>Since 6.6.0</span> the <code>cell</code> element can ++ have a <code>cache</code> child element which describes memory side cache ++ for memory proximity domains. The <code>cache</code> element has a ++ <code>level</code> attribute describing the cache level and thus the ++ element can be repeated multiple times to describe different levels of ++ the cache. ++ </p> ++ ++ <p> ++ The <code>cache</code> element then has following mandatory attributes: ++ </p> ++ ++ <dl> ++ <dt><code>level</code></dt> ++ <dd> ++ Level of the cache this description refers to. ++ </dd> ++ ++ <dt><code>associativity</code></dt> ++ <dd> ++ Describes cache associativity (accepted values are <code>none</code>, ++ <code>direct</code> and <code>full</code>). ++ </dd> ++ ++ <dt><code>policy</code></dt> ++ <dd> ++ Describes cache write associativity (accepted values are ++ <code>none</code>, <code>writeback</code> and ++ <code>writethrough</code>). ++ </dd> ++ </dl> ++ ++ <p> ++ The <code>cache</code> element has two mandatory child elements then: ++ <code>size</code> and <code>line</code> which describe cache size and ++ cache line size. Both elements accept two attributes: <code>value</code> ++ and <code>unit</code> which set the value of corresponding cache ++ attribute. ++ </p> ++ ++ <p> ++ The NUMA description has an optional <code>interconnects</code> element that ++ describes the normalized memory read/write latency, read/write bandwidth ++ between Initiator Proximity Domains (Processor or I/O) and Target ++ Proximity Domains (Memory). ++ </p> ++ ++ <p> ++ The <code>interconnects</code> element can have zero or more ++ <code>latency</code> child elements to describe latency between two ++ memory nodes and zero or more <code>bandwidth</code> child elements to ++ describe bandwidth between two memory nodes. Both these have the ++ following mandatory attributes: ++ </p> ++ ++ <dl> ++ <dt><code>initiator</code></dt> ++ <dd>Refers to the source NUMA node</dd> ++ ++ <dt><code>target</code></dt> ++ <dd>Refers to the target NUMA node</dd> ++ ++ <dt><code>type</code></dt> ++ <dd>The type of the access. Accepted values: <code>access</code>, ++ <code>read</code>, <code>write</code></dd> ++ ++ <dt><code>value</code></dt> ++ <dd>The actual value. For latency this is delay in nanoseconds, for ++ bandwidth this value is in kibibytes per second. Use additional ++ <code>unit</code> attribute to change the units.</dd> ++ </dl> ++ ++ <p> ++ To describe latency from one NUMA node to a cache of another NUMA node ++ the <code>latency</code> element has optional <code>cache</code> ++ attribute which in combination with <code>target</code> attribute creates ++ full reference to distant NUMA node's cache level. For instance, ++ <code>target='0' cache='1'</code> refers to the first level cache of NUMA ++ node 0. ++ </p> ++ + <h3><a id="elementsEvents">Events configuration</a></h3> + + <p> +diff --git a/docs/schemas/cputypes.rng b/docs/schemas/cputypes.rng +index a1682a1003..ba30dbf9ff 100644 +--- a/docs/schemas/cputypes.rng ++++ b/docs/schemas/cputypes.rng +@@ -102,9 +102,14 @@ + + <define name="cpuNuma"> + <element name="numa"> +- <oneOrMore> +- <ref name="numaCell"/> +- </oneOrMore> ++ <interleave> ++ <oneOrMore> ++ <ref name="numaCell"/> ++ </oneOrMore> ++ <optional> ++ <ref name="numaInterconnects"/> ++ </optional> ++ </interleave> + </element> + </define> + +@@ -148,6 +153,9 @@ + </oneOrMore> + </element> + </optional> ++ <zeroOrMore> ++ <ref name="numaCache"/> ++ </zeroOrMore> + </element> + </define> + +@@ -162,6 +170,102 @@ + </element> + </define> + ++ <define name="numaCache"> ++ <element name="cache"> ++ <attribute name="level"> ++ <ref name="unsignedInt"/> ++ </attribute> ++ <attribute name="associativity"> ++ <choice> ++ <value>none</value> ++ <value>direct</value> ++ <value>full</value> ++ </choice> ++ </attribute> ++ <attribute name="policy"> ++ <choice> ++ <value>none</value> ++ <value>writeback</value> ++ <value>writethrough</value> ++ </choice> ++ </attribute> ++ <interleave> ++ <element name="size"> ++ <attribute name="value"> ++ <ref name="unsignedInt"/> ++ </attribute> ++ <attribute name="unit"> ++ <ref name="unit"/> ++ </attribute> ++ </element> ++ <element name="line"> ++ <attribute name="value"> ++ <ref name="unsignedInt"/> ++ </attribute> ++ <attribute name="unit"> ++ <ref name="unit"/> ++ </attribute> ++ </element> ++ </interleave> ++ </element> ++ </define> ++ ++ <define name="numaInterconnects"> ++ <element name="interconnects"> ++ <interleave> ++ <zeroOrMore> ++ <element name="latency"> ++ <attribute name="initiator"> ++ <ref name="unsignedInt"/> ++ </attribute> ++ <attribute name="target"> ++ <ref name="unsignedInt"/> ++ </attribute> ++ <optional> ++ <attribute name="cache"> ++ <ref name="unsignedInt"/> ++ </attribute> ++ </optional> ++ <attribute name="type"> ++ <choice> ++ <value>access</value> ++ <value>read</value> ++ <value>write</value> ++ </choice> ++ </attribute> ++ <attribute name="value"> ++ <ref name="unsignedInt"/> ++ </attribute> ++ <empty/> ++ </element> ++ </zeroOrMore> ++ <zeroOrMore> ++ <element name="bandwidth"> ++ <attribute name="initiator"> ++ <ref name="unsignedInt"/> ++ </attribute> ++ <attribute name="target"> ++ <ref name="unsignedInt"/> ++ </attribute> ++ <attribute name="type"> ++ <choice> ++ <value>access</value> ++ <value>read</value> ++ <value>write</value> ++ </choice> ++ </attribute> ++ <attribute name="value"> ++ <ref name="unsignedInt"/> ++ </attribute> ++ <attribute name="unit"> ++ <ref name="unit"/> ++ </attribute> ++ </element> ++ </zeroOrMore> ++ </interleave> ++ </element> ++ </define> ++ + <!-- Memory as an attribute is in KiB, no way to express a unit --> + <define name="memoryKB"> + <data type="unsignedLong"/> +diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c +index a805336d16..5c764190c3 100644 +--- a/src/conf/numa_conf.c ++++ b/src/conf/numa_conf.c +@@ -59,9 +59,37 @@ VIR_ENUM_IMPL(virDomainMemoryAccess, + "private", + ); + ++VIR_ENUM_IMPL(virDomainCacheAssociativity, ++ VIR_DOMAIN_CACHE_ASSOCIATIVITY_LAST, ++ "none", ++ "direct", ++ "full", ++); ++ ++VIR_ENUM_IMPL(virDomainCachePolicy, ++ VIR_DOMAIN_CACHE_POLICY_LAST, ++ "none", ++ "writeback", ++ "writethrough", ++); ++ ++VIR_ENUM_IMPL(virDomainMemoryLatency, ++ VIR_DOMAIN_MEMORY_LATENCY_LAST, ++ "none", ++ "access", ++ "read", ++ "write" ++); ++ + typedef struct _virDomainNumaDistance virDomainNumaDistance; + typedef virDomainNumaDistance *virDomainNumaDistancePtr; + ++typedef struct _virDomainNumaCache virDomainNumaCache; ++typedef virDomainNumaCache *virDomainNumaCachePtr; ++ ++typedef struct _virDomainNumaInterconnect virDomainNumaInterconnect; ++typedef virDomainNumaInterconnect *virDomainNumaInterconnectPtr; ++ + typedef struct _virDomainNumaNode virDomainNumaNode; + typedef virDomainNumaNode *virDomainNumaNodePtr; + +@@ -86,9 +114,30 @@ struct _virDomainNuma { + unsigned int cellid; + } *distances; /* remote node distances */ + size_t ndistances; ++ ++ struct _virDomainNumaCache { ++ unsigned int level; /* cache level */ ++ unsigned int size; /* cache size */ ++ unsigned int line; /* line size, !!! in bytes !!! */ ++ virDomainCacheAssociativity associativity; /* cache associativity */ ++ virDomainCachePolicy policy; /* cache policy */ ++ } *caches; ++ size_t ncaches; + } *mem_nodes; /* guest node configuration */ + size_t nmem_nodes; + ++ struct _virDomainNumaInterconnect { ++ virDomainNumaInterconnectType type; /* whether structure describes latency ++ or bandwidth */ ++ unsigned int initiator; /* the initiator NUMA node */ ++ unsigned int target; /* the target NUMA node */ ++ unsigned int cache; /* the target cache on @target; if 0 then the ++ memory on @target */ ++ virDomainMemoryLatency accessType; /* what type of access is defined */ ++ unsigned long value; /* value itself */ ++ } *interconnects; ++ size_t ninterconnects; ++ + /* Future NUMA tuning related stuff should go here. */ + }; + +@@ -368,9 +417,13 @@ virDomainNumaFree(virDomainNumaPtr numa) + + if (numa->mem_nodes[i].ndistances > 0) + VIR_FREE(numa->mem_nodes[i].distances); ++ ++ VIR_FREE(numa->mem_nodes[i].caches); + } + VIR_FREE(numa->mem_nodes); + ++ VIR_FREE(numa->interconnects); ++ + VIR_FREE(numa); + } + +@@ -841,6 +894,97 @@ virDomainNumaDefNodeDistanceParseXML(virDomainNumaPtr def, + return ret; + } + ++ ++static int ++virDomainNumaDefNodeCacheParseXML(virDomainNumaPtr def, ++ xmlXPathContextPtr ctxt, ++ unsigned int cur_cell) ++{ ++ g_autofree xmlNodePtr *nodes = NULL; ++ int n; ++ size_t i; ++ ++ if ((n = virXPathNodeSet("./cache", ctxt, &nodes)) < 0) ++ return -1; ++ ++ def->mem_nodes[cur_cell].caches = g_new0(virDomainNumaCache, n); ++ ++ for (i = 0; i < n; i++) { ++ VIR_XPATH_NODE_AUTORESTORE(ctxt); ++ virDomainNumaCachePtr cache = &def->mem_nodes[cur_cell].caches[i]; ++ g_autofree char *tmp = NULL; ++ unsigned int level; ++ int associativity; ++ int policy; ++ unsigned long long size; ++ unsigned long long line; ++ ++ if (!(tmp = virXMLPropString(nodes[i], "level"))) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("Missing 'level' attribute in cache " ++ "element for NUMA node %d"), ++ cur_cell); ++ return -1; ++ } ++ ++ if (virStrToLong_uip(tmp, NULL, 10, &level) < 0 || ++ level == 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("Invalid 'level' attribute in cache " ++ "element for NUMA node %d"), ++ cur_cell); ++ return -1; ++ } ++ VIR_FREE(tmp); ++ ++ if (!(tmp = virXMLPropString(nodes[i], "associativity"))) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("Missing 'associativity' attribute in cache " ++ "element for NUMA node %d"), ++ cur_cell); ++ return -1; ++ } ++ ++ if ((associativity = virDomainCacheAssociativityTypeFromString(tmp)) < 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("Invalid cache associativity '%s'"), ++ tmp); ++ return -1; ++ } ++ VIR_FREE(tmp); ++ ++ if (!(tmp = virXMLPropString(nodes[i], "policy"))) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("Missing 'policy' attribute in cache " ++ "element for NUMA node %d"), ++ cur_cell); ++ } ++ ++ if ((policy = virDomainCachePolicyTypeFromString(tmp)) < 0) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("Invalid cache policy '%s'"), ++ tmp); ++ return -1; ++ } ++ VIR_FREE(tmp); ++ ++ ctxt->node = nodes[i]; ++ if (virDomainParseMemory("./size/@value", "./size/unit", ++ ctxt, &size, true, false) < 0) ++ return -1; ++ ++ if (virParseScaledValue("./line/@value", "./line/unit", ++ ctxt, &line, 1, ULLONG_MAX, true) < 0) ++ return -1; ++ ++ *cache = (virDomainNumaCache){level, size, line, associativity, policy}; ++ def->mem_nodes[cur_cell].ncaches++; ++ } ++ ++ return 0; ++} ++ ++ + int + virDomainNumaDefParseXML(virDomainNumaPtr def, + xmlXPathContextPtr ctxt) +@@ -867,6 +1011,7 @@ virDomainNumaDefParseXML(virDomainNumaPtr def, + def->nmem_nodes = n; + + for (i = 0; i < n; i++) { ++ VIR_XPATH_NODE_AUTORESTORE(ctxt); + int rc; + unsigned int cur_cell = i; + +@@ -953,7 +1098,109 @@ virDomainNumaDefParseXML(virDomainNumaPtr def, + + /* Parse NUMA distances info */ + if (virDomainNumaDefNodeDistanceParseXML(def, ctxt, cur_cell) < 0) ++ goto cleanup; ++ ++ /* Parse cache info */ ++ if (virDomainNumaDefNodeCacheParseXML(def, ctxt, cur_cell) < 0) ++ goto cleanup; ++ } ++ ++ VIR_FREE(nodes); ++ if ((n = virXPathNodeSet("./cpu/numa[1]/interconnects[1]/latency|" ++ "./cpu/numa[1]/interconnects[1]/bandwidth", ctxt, &nodes)) < 0) ++ goto cleanup; ++ ++ def->interconnects = g_new0(virDomainNumaInterconnect, n); ++ for (i = 0; i < n; i++) { ++ virDomainNumaInterconnectType type; ++ unsigned int initiator; ++ unsigned int target; ++ unsigned int cache = 0; ++ int accessType; ++ unsigned long long value; ++ ++ if (virXMLNodeNameEqual(nodes[i], "latency")) { ++ type = VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_LATENCY; ++ ++ if (!(tmp = virXMLPropString(nodes[i], "value"))) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Missing 'value' attribute in NUMA interconnects")); + goto cleanup; ++ } ++ ++ if (virStrToLong_ullp(tmp, NULL, 10, &value) < 0) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Invalid 'value' attribute in NUMA interconnects")); ++ goto cleanup; ++ } ++ VIR_FREE(tmp); ++ } else if (virXMLNodeNameEqual(nodes[i], "bandwidth")) { ++ VIR_XPATH_NODE_AUTORESTORE(ctxt); ++ type = VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_BANDWIDTH; ++ ++ ctxt->node = nodes[i]; ++ ++ if (virDomainParseMemory("./@value", "./@unit", ctxt, &value, true, false) < 0) ++ goto cleanup; ++ } else { ++ /* Ignore yet unknown child elements. */ ++ continue; ++ } ++ ++ if (!(tmp = virXMLPropString(nodes[i], "initiator"))) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Missing 'initiator' attribute in NUMA interconnects")); ++ goto cleanup; ++ } ++ ++ if (virStrToLong_uip(tmp, NULL, 10, &initiator) < 0) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Invalid 'initiator' attribute in NUMA interconnects")); ++ goto cleanup; ++ } ++ VIR_FREE(tmp); ++ ++ if (!(tmp = virXMLPropString(nodes[i], "target"))) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Missing 'target' attribute in NUMA interconnects")); ++ goto cleanup; ++ } ++ ++ if (virStrToLong_uip(tmp, NULL, 10, &target) < 0) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Invalid 'target' attribute in NUMA interconnects")); ++ goto cleanup; ++ } ++ VIR_FREE(tmp); ++ ++ ++ /* cache attribute is optional */ ++ if ((tmp = virXMLPropString(nodes[i], "cache"))) { ++ if (virStrToLong_uip(tmp, NULL, 10, &cache) < 0 || ++ cache == 0) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Invalid 'cache' attribute in NUMA interconnects")); ++ goto cleanup; ++ } ++ } ++ VIR_FREE(tmp); ++ ++ if (!(tmp = virXMLPropString(nodes[i], "type"))) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Missing 'type' attribute in NUMA interconnects")); ++ goto cleanup; ++ } ++ ++ if ((accessType = virDomainMemoryLatencyTypeFromString(tmp)) <= 0) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Invalid 'type' attribute in NUMA interconnects")); ++ goto cleanup; ++ } ++ VIR_FREE(tmp); ++ ++ def->interconnects[i] = (virDomainNumaInterconnect) {type, initiator, target, ++ cache, accessType, value}; ++ def->ninterconnects++; + } + + ret = 0; +@@ -983,6 +1230,7 @@ virDomainNumaDefFormatXML(virBufferPtr buf, + for (i = 0; i < ncells; i++) { + virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(def, i); + int ndistances; ++ size_t ncaches; + + memAccess = virDomainNumaGetNodeMemoryAccessMode(def, i); + discard = virDomainNumaGetNodeDiscard(def, i); +@@ -1009,30 +1257,107 @@ virDomainNumaDefFormatXML(virBufferPtr buf, + virTristateBoolTypeToString(discard)); + + ndistances = def->mem_nodes[i].ndistances; +- if (ndistances == 0) { ++ ncaches = def->mem_nodes[i].ncaches; ++ if (ndistances == 0 && ncaches == 0) { + virBufferAddLit(buf, "/>\n"); + } else { + size_t j; +- virDomainNumaDistancePtr distances = def->mem_nodes[i].distances; + + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 2); +- virBufferAddLit(buf, "<distances>\n"); +- virBufferAdjustIndent(buf, 2); +- for (j = 0; j < ndistances; j++) { +- if (distances[j].value) { +- virBufferAddLit(buf, "<sibling"); +- virBufferAsprintf(buf, " id='%d'", distances[j].cellid); +- virBufferAsprintf(buf, " value='%d'", distances[j].value); +- virBufferAddLit(buf, "/>\n"); ++ ++ if (ndistances) { ++ virDomainNumaDistancePtr distances = def->mem_nodes[i].distances; ++ ++ virBufferAddLit(buf, "<distances>\n"); ++ virBufferAdjustIndent(buf, 2); ++ for (j = 0; j < ndistances; j++) { ++ if (distances[j].value) { ++ virBufferAddLit(buf, "<sibling"); ++ virBufferAsprintf(buf, " id='%d'", distances[j].cellid); ++ virBufferAsprintf(buf, " value='%d'", distances[j].value); ++ virBufferAddLit(buf, "/>\n"); ++ } + } ++ virBufferAdjustIndent(buf, -2); ++ virBufferAddLit(buf, "</distances>\n"); ++ } ++ ++ for (j = 0; j < ncaches; j++) { ++ virDomainNumaCachePtr cache = &def->mem_nodes[i].caches[j]; ++ ++ virBufferAsprintf(buf, "<cache level='%u'", cache->level); ++ if (cache->associativity) { ++ virBufferAsprintf(buf, " associativity='%s'", ++ virDomainCacheAssociativityTypeToString(cache->associativity)); ++ } ++ ++ if (cache->policy) { ++ virBufferAsprintf(buf, " policy='%s'", ++ virDomainCachePolicyTypeToString(cache->policy)); ++ } ++ virBufferAddLit(buf, ">\n"); ++ ++ virBufferAdjustIndent(buf, 2); ++ virBufferAsprintf(buf, ++ "<size value='%u' unit='KiB'/>\n", ++ cache->size); ++ ++ if (cache->line) { ++ virBufferAsprintf(buf, ++ "<line value='%u' unit='B'/>\n", ++ cache->line); ++ } ++ ++ virBufferAdjustIndent(buf, -2); ++ virBufferAddLit(buf, "</cache>\n"); + } +- virBufferAdjustIndent(buf, -2); +- virBufferAddLit(buf, "</distances>\n"); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</cell>\n"); + } + } ++ ++ if (def->ninterconnects) { ++ virBufferAddLit(buf, "<interconnects>\n"); ++ virBufferAdjustIndent(buf, 2); ++ } ++ ++ for (i = 0; i < def->ninterconnects; i++) { ++ virDomainNumaInterconnectPtr l = &def->interconnects[i]; ++ ++ switch (l->type) { ++ case VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_LATENCY: ++ virBufferAddLit(buf, "<latency"); ++ break; ++ case VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_BANDWIDTH: ++ virBufferAddLit(buf, "<bandwidth"); ++ } ++ ++ virBufferAsprintf(buf, ++ " initiator='%u' target='%u'", ++ l->initiator, l->target); ++ ++ if (l->cache > 0) { ++ virBufferAsprintf(buf, ++ " cache='%u'", ++ l->cache); ++ } ++ ++ virBufferAsprintf(buf, ++ " type='%s' value='%lu'", ++ virDomainMemoryLatencyTypeToString(l->accessType), ++ l->value); ++ ++ if (l->type == VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_BANDWIDTH) ++ virBufferAddLit(buf, " unit='KiB'"); ++ virBufferAddLit(buf, "/>\n"); ++ } ++ ++ if (def->ninterconnects) { ++ virBufferAdjustIndent(buf, -2); ++ virBufferAddLit(buf, "</interconnects>\n"); ++ } ++ + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</numa>\n"); + +diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h +index 6808439a7c..5043c5a6d4 100644 +--- a/src/conf/numa_conf.h ++++ b/src/conf/numa_conf.h +@@ -52,6 +52,39 @@ typedef enum { + } virDomainMemoryAccess; + VIR_ENUM_DECL(virDomainMemoryAccess); + ++typedef enum { ++ VIR_DOMAIN_CACHE_ASSOCIATIVITY_NONE, /* No associativity */ ++ VIR_DOMAIN_CACHE_ASSOCIATIVITY_DIRECT, /* Direct mapped cache */ ++ VIR_DOMAIN_CACHE_ASSOCIATIVITY_FULL, /* Fully associative cache */ ++ ++ VIR_DOMAIN_CACHE_ASSOCIATIVITY_LAST ++} virDomainCacheAssociativity; ++VIR_ENUM_DECL(virDomainCacheAssociativity); ++ ++typedef enum { ++ VIR_DOMAIN_CACHE_POLICY_NONE, /* No policy */ ++ VIR_DOMAIN_CACHE_POLICY_WRITEBACK, /* Write-back policy */ ++ VIR_DOMAIN_CACHE_POLICY_WRITETHROUGH, /* Write-through policy */ ++ ++ VIR_DOMAIN_CACHE_POLICY_LAST ++} virDomainCachePolicy; ++VIR_ENUM_DECL(virDomainCachePolicy); ++ ++typedef enum { ++ VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_LATENCY, ++ VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_BANDWIDTH, ++} virDomainNumaInterconnectType; ++ ++typedef enum { ++ VIR_DOMAIN_MEMORY_LATENCY_NONE = 0, /* No memory latency defined */ ++ VIR_DOMAIN_MEMORY_LATENCY_ACCESS, /* Access latency */ ++ VIR_DOMAIN_MEMORY_LATENCY_READ, /* Read latency */ ++ VIR_DOMAIN_MEMORY_LATENCY_WRITE, /* Write latency */ ++ ++ VIR_DOMAIN_MEMORY_LATENCY_LAST ++} virDomainMemoryLatency; ++VIR_ENUM_DECL(virDomainMemoryLatency); ++ + + virDomainNumaPtr virDomainNumaNew(void); + void virDomainNumaFree(virDomainNumaPtr numa); +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index acb25eb8c8..de95e3b116 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -808,8 +808,14 @@ virNodeDeviceDeleteVport; + virNodeDeviceGetParentName; + + # conf/numa_conf.h ++virDomainCacheAssociativityTypeFromString; ++virDomainCacheAssociativityTypeToString; ++virDomainCachePolicyTypeFromString; ++virDomainCachePolicyTypeToString; + virDomainMemoryAccessTypeFromString; + virDomainMemoryAccessTypeToString; ++virDomainMemoryLatencyTypeFromString; ++virDomainMemoryLatencyTypeToString; + virDomainNumaCheckABIStability; + virDomainNumaEquals; + virDomainNumaFree; +diff --git a/tests/qemuxml2argvdata/numatune-hmat.xml b/tests/qemuxml2argvdata/numatune-hmat.xml +new file mode 100644 +index 0000000000..83f0b56c9b +--- /dev/null ++++ b/tests/qemuxml2argvdata/numatune-hmat.xml +@@ -0,0 +1,52 @@ ++<domain type='qemu'> ++ <name>QEMUGuest</name> ++ <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid> ++ <memory unit='KiB'>8388608</memory> ++ <currentMemory unit='KiB'>8388608</currentMemory> ++ <vcpu placement='static'>12</vcpu> ++ <os> ++ <type arch='x86_64' machine='pc'>hvm</type> ++ <boot dev='hd'/> ++ </os> ++ <features> ++ <acpi/> ++ <apic/> ++ <pae/> ++ </features> ++ <cpu> ++ <numa> ++ <cell id='0' cpus='0-3' memory='2097152' unit='KiB'> ++ <cache level='1' associativity='direct' policy='writeback'> ++ <size value='10' unit='KiB'/> ++ <line value='8' unit='B'/> ++ </cache> ++ </cell> ++ <cell id='1' cpus='4-7' memory='2097152' unit='KiB'/> ++ <cell id='2' cpus='8-11' memory='2097152' unit='KiB'/> ++ <cell id='3' memory='2097152' unit='KiB'/> ++ <cell id='4' memory='2097152' unit='KiB'/> ++ <cell id='5' memory='2097152' unit='KiB'/> ++ <interconnects> ++ <latency initiator='0' target='0' type='access' value='5'/> ++ <latency initiator='0' target='0' cache='1' type='access' value='10'/> ++ <bandwidth initiator='0' target='0' type='access' value='204800' unit='KiB'/> ++ </interconnects> ++ </numa> ++ </cpu> ++ <clock offset='utc'/> ++ <on_poweroff>destroy</on_poweroff> ++ <on_reboot>restart</on_reboot> ++ <on_crash>restart</on_crash> ++ <devices> ++ <emulator>/usr/bin/qemu-system-x86_64</emulator> ++ <controller type='usb' index='0'> ++ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> ++ </controller> ++ <controller type='pci' index='0' model='pci-root'/> ++ <input type='mouse' bus='ps2'/> ++ <input type='keyboard' bus='ps2'/> ++ <memballoon model='virtio'> ++ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> ++ </memballoon> ++ </devices> ++</domain> +diff --git a/tests/qemuxml2xmloutdata/numatune-hmat.xml b/tests/qemuxml2xmloutdata/numatune-hmat.xml +new file mode 120000 +index 0000000000..6903a80ab1 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/numatune-hmat.xml +@@ -0,0 +1 @@ ++../qemuxml2argvdata/numatune-hmat.xml +\ No newline at end of file +diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c +index 1ddeba30f0..de1d720e1d 100644 +--- a/tests/qemuxml2xmltest.c ++++ b/tests/qemuxml2xmltest.c +@@ -1106,6 +1106,7 @@ mymain(void) + DO_TEST("numatune-memnode-no-memory", QEMU_CAPS_OBJECT_MEMORY_FILE); + DO_TEST("numatune-distances", QEMU_CAPS_NUMA, QEMU_CAPS_NUMA_DIST); + DO_TEST("numatune-no-vcpu", QEMU_CAPS_NUMA); ++ DO_TEST("numatune-hmat", NONE); + + DO_TEST("bios-nvram", NONE); + DO_TEST("bios-nvram-os-interleave", NONE); +-- +2.29.2 + diff --git a/SOURCES/libvirt-conf-Validate-NUMA-HMAT-configuration.patch b/SOURCES/libvirt-conf-Validate-NUMA-HMAT-configuration.patch new file mode 100644 index 0000000..1ca6905 --- /dev/null +++ b/SOURCES/libvirt-conf-Validate-NUMA-HMAT-configuration.patch @@ -0,0 +1,166 @@ +From 0ae283a1cb5224f3eb4fa32706e9b9c212577e51 Mon Sep 17 00:00:00 2001 +Message-Id: <0ae283a1cb5224f3eb4fa32706e9b9c212577e51@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Wed, 7 Oct 2020 18:45:40 +0200 +Subject: [PATCH] conf: Validate NUMA HMAT configuration +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There are several restrictions, for instance @initiator and +@target have to refer to existing NUMA nodes (daa), @cache has to +refer to a defined cache level and so on. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit f0611fe8830543d03d1871422f8c542453f0c8db) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <e8488a2e49fa251dd0e2ab51f5ab627e3b265440.1602087923.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/conf/domain_conf.c | 3 ++ + src/conf/numa_conf.c | 99 ++++++++++++++++++++++++++++++++++++++++++ + src/conf/numa_conf.h | 1 + + 3 files changed, 103 insertions(+) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 3229d5ec95..f41559f33e 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -7144,6 +7144,9 @@ virDomainDefValidateInternal(const virDomainDef *def, + if (virDomainDefCputuneValidate(def) < 0) + return -1; + ++ if (virDomainNumaDefValidate(def->numa) < 0) ++ return -1; ++ + return 0; + } + +diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c +index 5c764190c3..c90fb01bb6 100644 +--- a/src/conf/numa_conf.c ++++ b/src/conf/numa_conf.c +@@ -1365,6 +1365,105 @@ virDomainNumaDefFormatXML(virBufferPtr buf, + } + + ++int ++virDomainNumaDefValidate(const virDomainNuma *def) ++{ ++ size_t i; ++ size_t j; ++ ++ if (!def) ++ return 0; ++ ++ for (i = 0; i < def->nmem_nodes; i++) { ++ const virDomainNumaNode *node = &def->mem_nodes[i]; ++ g_autoptr(virBitmap) levelsSeen = virBitmapNewEmpty(); ++ ++ for (j = 0; j < node->ncaches; j++) { ++ const virDomainNumaCache *cache = &node->caches[j]; ++ ++ /* Relax this if there's ever fourth layer of cache */ ++ if (cache->level > 3) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Ain't nobody heard of that much cache level")); ++ return -1; ++ } ++ ++ if (virBitmapIsBitSet(levelsSeen, cache->level)) { ++ virReportError(VIR_ERR_XML_ERROR, ++ _("Cache level '%u' already defined"), ++ cache->level); ++ return -1; ++ } ++ ++ if (virBitmapSetBitExpand(levelsSeen, cache->level)) ++ return -1; ++ } ++ } ++ ++ for (i = 0; i < def->ninterconnects; i++) { ++ const virDomainNumaInterconnect *l = &def->interconnects[i]; ++ ++ if (l->initiator >= def->nmem_nodes) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("'initiator' refers to a non-existent NUMA node")); ++ return -1; ++ } ++ ++ if (l->target >= def->nmem_nodes) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("'target' refers to a non-existent NUMA node")); ++ return -1; ++ } ++ ++ if (!def->mem_nodes[l->initiator].cpumask) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("NUMA nodes without CPUs can't be initiator")); ++ return -1; ++ } ++ ++ if (l->cache > 0) { ++ for (j = 0; j < def->mem_nodes[l->target].ncaches; j++) { ++ const virDomainNumaCache *cache = def->mem_nodes[l->target].caches; ++ ++ if (l->cache == cache->level) ++ break; ++ } ++ ++ if (j == def->mem_nodes[l->target].ncaches) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("'cache' refers to a non-existent NUMA node cache")); ++ return -1; ++ } ++ } ++ ++ for (j = 0; j < i; j++) { ++ const virDomainNumaInterconnect *ll = &def->interconnects[j]; ++ ++ if (l->type == ll->type && ++ l->initiator == ll->initiator && ++ l->target == ll->target && ++ l->cache == ll->cache && ++ l->accessType == ll->accessType) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Duplicate info for NUMA latencies")); ++ return -1; ++ } ++ ++ ++ if (l->initiator != l->target && ++ l->initiator == ll->target && ++ l->target == ll->initiator) { ++ virReportError(VIR_ERR_XML_ERROR, "%s", ++ _("Link already defined")); ++ return -1; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++ + unsigned int + virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa) + { +diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h +index 5043c5a6d4..2963004c94 100644 +--- a/src/conf/numa_conf.h ++++ b/src/conf/numa_conf.h +@@ -217,5 +217,6 @@ bool virDomainNumatuneNodeSpecified(virDomainNumaPtr numatune, + + int virDomainNumaDefParseXML(virDomainNumaPtr def, xmlXPathContextPtr ctxt); + int virDomainNumaDefFormatXML(virBufferPtr buf, virDomainNumaPtr def); ++int virDomainNumaDefValidate(const virDomainNuma *def); + + unsigned int virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa); +-- +2.29.2 + diff --git a/SOURCES/libvirt-conf-properly-clear-out-autogenerated-macvtap-names-when-formatting-parsing.patch b/SOURCES/libvirt-conf-properly-clear-out-autogenerated-macvtap-names-when-formatting-parsing.patch new file mode 100644 index 0000000..0133af5 --- /dev/null +++ b/SOURCES/libvirt-conf-properly-clear-out-autogenerated-macvtap-names-when-formatting-parsing.patch @@ -0,0 +1,117 @@ +From b2e0155b59ae9f038bcf21da7c6b7fb0a99a7b67 Mon Sep 17 00:00:00 2001 +Message-Id: <b2e0155b59ae9f038bcf21da7c6b7fb0a99a7b67@dist-git> +From: Laine Stump <laine@redhat.com> +Date: Tue, 1 Dec 2020 22:01:00 -0500 +Subject: [PATCH] conf: properly clear out autogenerated macvtap names when + formatting/parsing + +Back when macvtap support was added in commit 315baab9443 in Feb. 2010 +(libvirt-0.7.7), it was setup to autogenerate a name for the device if +one wasn't supplied, in the pattern "macvtap%d" (or "macvlan%d"), +similar to the way an unspecified standard tap device name will lead +to an autogenerated "vnet%d". + +As a matter of fact, in commit ca1b7cc8e45 added in May 2010, the code +was changed to *always* ignore a supplied device name for macvtap +interfaces by deleting *any* name immediately during the <interface> +parsing (this was intended to prevent one domain which had failed to +completely start from deleting the macvtap device of another domain +which had subsequently been provided the same device name (this will +seem mildly ironic later). This was later fixed to only clear the +device name when inactive XML was being parsed. HOWEVER - this was +only done if the xml was <interface type='direct'> - autogenerated +names were not cleared for <interface type='network'> (which could +also result in a macvtap device). + +Although the names of "vnetX" tap devices had always been +automatically cleared when parsing <interface> (see commit d1304583d +from July 2008 (!)), at the time macvtap support was added, both vnetX +and macvtapX device names were always included when formatting the +XML. + +Then in commit a8be259d0cc (July 2011, libvirt-0.9.4), <interface> +formatting was changed to also clear out "vnetX" device names during +XML formatting as well. However the same treatment wasn't given to +"macvtapX". + +Now in 2020, there has been a report that a failed migration leads to +the macvtap device of some other unrelated guest on the destination +host losing its network connectivity. It was determined that this was +due to the domain XML in the migration containing a macvtap device +name, e.g. "macvtap0", that was already in use by the other guest on +the destination. Normally this wouldn't be a problem, because libvirt +would see that the device was already in use, and then find a +different unused name. But in this case, other external problems were +causing the migration to fail prior to selecting a macvtap device and +successfully opening it, and during error recovery, qemuProcessStop() +was called, which went through all def->nets objects and (if they were +macvtap) deleted the device specified in net->ifname; since libvirt +hadn't gotten to the point of replacing the incoming "macvtap0" with +the name of a device it actually created for this guest, that meant +that "macvtap0" was deleted, *even though it was currently in use by a +different guest*! + +Whew! + +So, it turns out that when formatting "migratable" XML, "vnetX" +devices are omitted, just as when formatting "inactive" XML. By making +the code in both interface parsing and formatting consistent for +"vnetX", "macvtapX", and "macvlanX", we can thus make sure that the +autogenerated (and unneeded / completely *not* wanted) macvtap device +name will not be sent with the migration XML. This way when a +migration fails, net->ifname will be NULL, and libvirt won't have any +device to try and (erroneously) delete. + +Signed-off-by: Laine Stump <laine@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit 282d135ddbb7203565cd5527b451469b14953994) + +https://bugzilla.redhat.com/1872610 + +Signed-off-by: Laine Stump <laine@redhat.com> +Message-Id: <20201202030100.458879-1-laine@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +--- + src/conf/domain_conf.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index f41559f33e..cd5c15f297 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -12183,14 +12183,6 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, + } + + def->data.direct.linkdev = g_steal_pointer(&dev); +- +- if (ifname && +- flags & VIR_DOMAIN_DEF_PARSE_INACTIVE && +- (STRPREFIX(ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) || +- STRPREFIX(ifname, VIR_NET_GENERATED_MACVLAN_PREFIX))) { +- VIR_FREE(ifname); +- } +- + break; + + case VIR_DOMAIN_NET_TYPE_HOSTDEV: +@@ -12238,6 +12230,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, + if (def->managed_tap != VIR_TRISTATE_BOOL_NO && ifname && + (flags & VIR_DOMAIN_DEF_PARSE_INACTIVE) && + (STRPREFIX(ifname, VIR_NET_GENERATED_TAP_PREFIX) || ++ STRPREFIX(ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) || ++ STRPREFIX(ifname, VIR_NET_GENERATED_MACVLAN_PREFIX) || + (prefix && STRPREFIX(ifname, prefix)))) { + /* An auto-generated target name, blank it out */ + VIR_FREE(ifname); +@@ -25996,6 +25990,8 @@ virDomainNetDefFormat(virBufferPtr buf, + (def->managed_tap == VIR_TRISTATE_BOOL_NO || + !((flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE) && + (STRPREFIX(def->ifname, VIR_NET_GENERATED_TAP_PREFIX) || ++ STRPREFIX(def->ifname, VIR_NET_GENERATED_MACVTAP_PREFIX) || ++ STRPREFIX(def->ifname, VIR_NET_GENERATED_MACVLAN_PREFIX) || + (prefix && STRPREFIX(def->ifname, prefix)))))) { + /* Skip auto-generated target names for inactive config. */ + virBufferEscapeString(&attrBuf, " dev='%s'", def->ifname); +-- +2.29.2 + diff --git a/SOURCES/libvirt-cpu_map-Add-EPYC-Milan-x86-CPU-model.patch b/SOURCES/libvirt-cpu_map-Add-EPYC-Milan-x86-CPU-model.patch new file mode 100644 index 0000000..3257983 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-EPYC-Milan-x86-CPU-model.patch @@ -0,0 +1,145 @@ +From b5716d1b191eb52cd88d7b94cb9bf0186f3e427b Mon Sep 17 00:00:00 2001 +Message-Id: <b5716d1b191eb52cd88d7b94cb9bf0186f3e427b@dist-git> +From: Jiri Denemark <jdenemar@redhat.com> +Date: Wed, 3 Mar 2021 11:11:54 +0100 +Subject: [PATCH] cpu_map: Add EPYC-Milan x86 CPU model +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduced in QEMU 6.0.0 by 623972ceae091b31331ae4a1dc94fe5cbb891937 + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +(cherry picked from commit f321a4822e9fa6542e48a78611989ecd9acaa83a) + +https://bugzilla.redhat.com/show_bug.cgi?id=1926864 + +Conflicts: + src/cpu_map/index.xml + - context: commit 82bebba1803c63a733e17f5ab2618e020e4abd8d + "cpu_map: Unify apostrophe and quotation mark usage" was + not backported + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Message-Id: <715abc0f90faafb7daa193dd24bad65046c36de0.1614766279.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/cpu_map/index.xml | 1 + + src/cpu_map/x86_EPYC-Milan.xml | 92 ++++++++++++++++++++++++++++++++++ + 2 files changed, 93 insertions(+) + create mode 100644 src/cpu_map/x86_EPYC-Milan.xml + +diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml +index 2f58261e6d..c3dda794b1 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -68,6 +68,7 @@ + <include filename="x86_EPYC.xml"/> + <include filename="x86_EPYC-IBPB.xml"/> + <include filename="x86_EPYC-Rome.xml"/> ++ <include filename='x86_EPYC-Milan.xml'/> + + <!-- Hygon CPU models --> + <include filename="x86_Dhyana.xml"/> +diff --git a/src/cpu_map/x86_EPYC-Milan.xml b/src/cpu_map/x86_EPYC-Milan.xml +new file mode 100644 +index 0000000000..53f0cd6aac +--- /dev/null ++++ b/src/cpu_map/x86_EPYC-Milan.xml +@@ -0,0 +1,92 @@ ++<cpus> ++ <model name='EPYC-Milan'> ++ <decode host='on' guest='on'/> ++ <signature family='25' model='1'/> ++ <vendor name='AMD'/> ++ <feature name='3dnowprefetch'/> ++ <feature name='abm'/> ++ <feature name='adx'/> ++ <feature name='aes'/> ++ <feature name='amd-ssbd'/> ++ <feature name='amd-stibp'/> ++ <feature name='apic'/> ++ <feature name='arat'/> ++ <feature name='avx'/> ++ <feature name='avx2'/> ++ <feature name='bmi1'/> ++ <feature name='bmi2'/> ++ <feature name='clflush'/> ++ <feature name='clflushopt'/> ++ <feature name='clwb'/> ++ <feature name='clzero'/> ++ <feature name='cmov'/> ++ <feature name='cr8legacy'/> ++ <feature name='cx16'/> ++ <feature name='cx8'/> ++ <feature name='de'/> ++ <feature name='erms'/> ++ <feature name='f16c'/> ++ <feature name='fma'/> ++ <feature name='fpu'/> ++ <feature name='fsgsbase'/> ++ <feature name='fsrm'/> ++ <feature name='fxsr'/> ++ <feature name='fxsr_opt'/> ++ <feature name='ibpb'/> ++ <feature name='ibrs'/> ++ <feature name='invpcid'/> ++ <feature name='lahf_lm'/> ++ <feature name='lm'/> ++ <feature name='mca'/> ++ <feature name='mce'/> ++ <feature name='misalignsse'/> ++ <feature name='mmx'/> ++ <feature name='mmxext'/> ++ <feature name='movbe'/> ++ <feature name='msr'/> ++ <feature name='mtrr'/> ++ <feature name='npt'/> ++ <feature name='nrip-save'/> ++ <feature name='nx'/> ++ <feature name='osvw'/> ++ <feature name='pae'/> ++ <feature name='pat'/> ++ <feature name='pcid'/> ++ <feature name='pclmuldq'/> ++ <feature name='pdpe1gb'/> ++ <feature name='perfctr_core'/> ++ <feature name='pge'/> ++ <feature name='pku'/> ++ <feature name='pni'/> ++ <feature name='popcnt'/> ++ <feature name='pse'/> ++ <feature name='pse36'/> ++ <feature name='rdpid'/> ++ <feature name='rdrand'/> ++ <feature name='rdseed'/> ++ <feature name='rdtscp'/> ++ <feature name='sep'/> ++ <feature name='sha-ni'/> ++ <feature name='smap'/> ++ <feature name='smep'/> ++ <feature name='sse'/> ++ <feature name='sse2'/> ++ <feature name='sse4.1'/> ++ <feature name='sse4.2'/> ++ <feature name='sse4a'/> ++ <feature name='ssse3'/> ++ <feature name='svm'/> ++ <feature name='svme-addr-check'/> ++ <feature name='syscall'/> ++ <feature name='tsc'/> ++ <feature name='umip'/> ++ <feature name='vme'/> ++ <feature name='wbnoinvd'/> ++ <feature name='xgetbv1'/> ++ <feature name='xsave'/> ++ <feature name='xsavec'/> ++ <feature name='xsaveerptr'/> ++ <feature name='xsaveopt'/> ++ <feature name='xsaves'/> ++ </model> ++</cpus> +-- +2.30.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-missing-AMD-SVM-features.patch b/SOURCES/libvirt-cpu_map-Add-missing-AMD-SVM-features.patch new file mode 100644 index 0000000..b907c79 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-missing-AMD-SVM-features.patch @@ -0,0 +1,896 @@ +From 5936216b6e32392d785979bfd6ccafc5174ec519 Mon Sep 17 00:00:00 2001 +Message-Id: <5936216b6e32392d785979bfd6ccafc5174ec519@dist-git> +From: Jiri Denemark <jdenemar@redhat.com> +Date: Thu, 8 Oct 2020 18:01:23 +0200 +Subject: [PATCH] cpu_map: Add missing AMD SVM features +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> +(cherry picked from commit 96a39aad705f8e37950109d11636085b212af790) + +https://bugzilla.redhat.com/show_bug.cgi?id=1861506 + +Conflicts: + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-disabled.xml + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-enabled.xml + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-guest.xml + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-host.xml + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-json.xml + tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml + tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml + tests/domaincapsdata/qemu_5.1.0.x86_64.xml + - not present downstream + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Message-Id: <d55a2ddfc9aefcc833d3a370c7d70dfb2c0b7554.1602172344.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/cpu_map/x86_features.xml | 32 +++++++++++++++++++ + .../x86_64-cpuid-A10-5800K-disabled.xml | 1 + + .../x86_64-cpuid-A10-5800K-enabled.xml | 1 + + .../x86_64-cpuid-A10-5800K-guest.xml | 10 ++++++ + .../x86_64-cpuid-A10-5800K-host.xml | 10 ++++++ + .../x86_64-cpuid-A10-5800K-json.xml | 2 ++ + ...86_64-cpuid-EPYC-7601-32-Core-disabled.xml | 1 + + ...x86_64-cpuid-EPYC-7601-32-Core-enabled.xml | 1 + + .../x86_64-cpuid-EPYC-7601-32-Core-guest.xml | 10 ++++++ + .../x86_64-cpuid-EPYC-7601-32-Core-host.xml | 10 ++++++ + ...-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml | 1 + + ...4-cpuid-EPYC-7601-32-Core-ibpb-enabled.xml | 1 + + ..._64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml | 10 ++++++ + ...6_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml | 10 ++++++ + ...6_64-cpuid-EPYC-7601-32-Core-ibpb-json.xml | 2 ++ + .../x86_64-cpuid-EPYC-7601-32-Core-json.xml | 2 ++ + .../x86_64-cpuid-FX-8150-guest.xml | 10 ++++++ + .../cputestdata/x86_64-cpuid-FX-8150-host.xml | 10 ++++++ + ...-cpuid-Hygon-C86-7185-32-core-disabled.xml | 1 + + ...4-cpuid-Hygon-C86-7185-32-core-enabled.xml | 1 + + ..._64-cpuid-Hygon-C86-7185-32-core-guest.xml | 10 ++++++ + ...6_64-cpuid-Hygon-C86-7185-32-core-host.xml | 10 ++++++ + ...6_64-cpuid-Hygon-C86-7185-32-core-json.xml | 2 ++ + .../x86_64-cpuid-Opteron-1352-guest.xml | 3 ++ + .../x86_64-cpuid-Opteron-1352-host.xml | 3 ++ + .../x86_64-cpuid-Opteron-2350-disabled.xml | 1 + + .../x86_64-cpuid-Opteron-2350-enabled.xml | 1 + + .../x86_64-cpuid-Opteron-2350-guest.xml | 3 ++ + .../x86_64-cpuid-Opteron-2350-host.xml | 3 ++ + .../x86_64-cpuid-Opteron-2350-json.xml | 1 + + .../x86_64-cpuid-Opteron-6234-disabled.xml | 1 + + .../x86_64-cpuid-Opteron-6234-enabled.xml | 1 + + .../x86_64-cpuid-Opteron-6234-guest.xml | 10 ++++++ + .../x86_64-cpuid-Opteron-6234-host.xml | 10 ++++++ + .../x86_64-cpuid-Opteron-6234-json.xml | 2 ++ + .../x86_64-cpuid-Opteron-6282-guest.xml | 10 ++++++ + .../x86_64-cpuid-Opteron-6282-host.xml | 10 ++++++ + .../x86_64-cpuid-Phenom-B95-disabled.xml | 1 + + .../x86_64-cpuid-Phenom-B95-enabled.xml | 1 + + .../x86_64-cpuid-Phenom-B95-guest.xml | 4 +++ + .../x86_64-cpuid-Phenom-B95-host.xml | 4 +++ + .../x86_64-cpuid-Phenom-B95-json.xml | 2 ++ + ...puid-Ryzen-7-1800X-Eight-Core-disabled.xml | 1 + + ...cpuid-Ryzen-7-1800X-Eight-Core-enabled.xml | 1 + + ...4-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml | 10 ++++++ + ...64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml | 10 ++++++ + ...64-cpuid-Ryzen-7-1800X-Eight-Core-json.xml | 2 ++ + .../domaincapsdata/qemu_3.0.0-tcg.x86_64.xml | 1 + + .../domaincapsdata/qemu_3.1.0-tcg.x86_64.xml | 1 + + .../domaincapsdata/qemu_4.0.0-tcg.x86_64.xml | 2 ++ + .../domaincapsdata/qemu_4.1.0-tcg.x86_64.xml | 2 ++ + .../domaincapsdata/qemu_4.2.0-tcg.x86_64.xml | 2 ++ + .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml | 2 ++ + .../cpu-host-model-cmt.x86_64-4.0.0.args | 6 ++-- + 54 files changed, 256 insertions(+), 3 deletions(-) + +diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml +index 5265b2989b..30d1375437 100644 +--- a/src/cpu_map/x86_features.xml ++++ b/src/cpu_map/x86_features.xml +@@ -508,6 +508,38 @@ + <cpuid eax_in='0x80000008' ebx='0x04000000'/> + </feature> + ++ <!-- SVM features --> ++ <feature name='npt'> ++ <cpuid eax_in='0x8000000a' edx='0x00000001'/> ++ </feature> ++ <feature name='lbrv'> ++ <cpuid eax_in='0x8000000a' edx='0x00000002'/> ++ </feature> ++ <feature name='svm-lock'> ++ <cpuid eax_in='0x8000000a' edx='0x00000004'/> ++ </feature> ++ <feature name='nrip-save'> ++ <cpuid eax_in='0x8000000a' edx='0x00000008'/> ++ </feature> ++ <feature name='tsc-scale'> ++ <cpuid eax_in='0x8000000a' edx='0x00000010'/> ++ </feature> ++ <feature name='vmcb-clean'> ++ <cpuid eax_in='0x8000000a' edx='0x00000020'/> ++ </feature> ++ <feature name='flushbyasid'> ++ <cpuid eax_in='0x8000000a' edx='0x00000040'/> ++ </feature> ++ <feature name='decodeassists'> ++ <cpuid eax_in='0x8000000a' edx='0x00000080'/> ++ </feature> ++ <feature name='pause-filter'> ++ <cpuid eax_in='0x8000000a' edx='0x00000400'/> ++ </feature> ++ <feature name='pfthreshold'> ++ <cpuid eax_in='0x8000000a' edx='0x00001000'/> ++ </feature> ++ + <!-- IA32_ARCH_CAPABILITIES features --> + <feature name='rdctl-no'> + <msr index='0x10a' edx='0x00000000' eax='0x00000001'/> +diff --git a/tests/cputestdata/x86_64-cpuid-A10-5800K-disabled.xml b/tests/cputestdata/x86_64-cpuid-A10-5800K-disabled.xml +index 6ed5b3573b..3bacf2cf95 100644 +--- a/tests/cputestdata/x86_64-cpuid-A10-5800K-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-A10-5800K-disabled.xml +@@ -3,4 +3,5 @@ + <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x08000008' edx='0x10000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01cab40c' edx='0x08000000'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x000014f6'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-A10-5800K-enabled.xml b/tests/cputestdata/x86_64-cpuid-A10-5800K-enabled.xml +index 5cae0b7130..f6afbe2cb3 100644 +--- a/tests/cputestdata/x86_64-cpuid-A10-5800K-enabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-A10-5800K-enabled.xml +@@ -3,4 +3,5 @@ + <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0xb6b83203' edx='0x078bfbff'/> + <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x0000000a' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00210bf3' edx='0x26500800'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-A10-5800K-guest.xml b/tests/cputestdata/x86_64-cpuid-A10-5800K-guest.xml +index 98a95e1c41..8401e53d30 100644 +--- a/tests/cputestdata/x86_64-cpuid-A10-5800K-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-A10-5800K-guest.xml +@@ -22,4 +22,14 @@ + <feature policy='require' name='perfctr_core'/> + <feature policy='require' name='perfctr_nb'/> + <feature policy='require' name='invtsc'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='lbrv'/> ++ <feature policy='require' name='svm-lock'/> ++ <feature policy='require' name='nrip-save'/> ++ <feature policy='require' name='tsc-scale'/> ++ <feature policy='require' name='vmcb-clean'/> ++ <feature policy='require' name='flushbyasid'/> ++ <feature policy='require' name='decodeassists'/> ++ <feature policy='require' name='pause-filter'/> ++ <feature policy='require' name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-A10-5800K-host.xml b/tests/cputestdata/x86_64-cpuid-A10-5800K-host.xml +index cb90c967a3..2430adbfbc 100644 +--- a/tests/cputestdata/x86_64-cpuid-A10-5800K-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-A10-5800K-host.xml +@@ -23,4 +23,14 @@ + <feature name='perfctr_core'/> + <feature name='perfctr_nb'/> + <feature name='invtsc'/> ++ <feature name='npt'/> ++ <feature name='lbrv'/> ++ <feature name='svm-lock'/> ++ <feature name='nrip-save'/> ++ <feature name='tsc-scale'/> ++ <feature name='vmcb-clean'/> ++ <feature name='flushbyasid'/> ++ <feature name='decodeassists'/> ++ <feature name='pause-filter'/> ++ <feature name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-A10-5800K-json.xml b/tests/cputestdata/x86_64-cpuid-A10-5800K-json.xml +index fa61b7b60b..51e6d2b660 100644 +--- a/tests/cputestdata/x86_64-cpuid-A10-5800K-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-A10-5800K-json.xml +@@ -11,6 +11,8 @@ + <feature policy='require' name='cmp_legacy'/> + <feature policy='require' name='cr8legacy'/> + <feature policy='require' name='osvw'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='nrip-save'/> + <feature policy='disable' name='rdtscp'/> + <feature policy='disable' name='svm'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml +index c26c9c7be3..25ef2d3314 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml +@@ -5,4 +5,5 @@ + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c2300c' edx='0x00000000'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> + <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x000014f6'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-enabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-enabled.xml +index 70b75f7115..e46908e981 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-enabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-enabled.xml +@@ -5,4 +5,5 @@ + <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x209c01ab' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000007' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x000003f3' edx='0x2e500800'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml +index 612e571609..0053913327 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml +@@ -15,4 +15,14 @@ + <feature policy='require' name='invtsc'/> + <feature policy='require' name='clzero'/> + <feature policy='require' name='xsaveerptr'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='lbrv'/> ++ <feature policy='require' name='svm-lock'/> ++ <feature policy='require' name='nrip-save'/> ++ <feature policy='require' name='tsc-scale'/> ++ <feature policy='require' name='vmcb-clean'/> ++ <feature policy='require' name='flushbyasid'/> ++ <feature policy='require' name='decodeassists'/> ++ <feature policy='require' name='pause-filter'/> ++ <feature policy='require' name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml +index 7498d924e2..7acab0a999 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml +@@ -16,4 +16,14 @@ + <feature name='invtsc'/> + <feature name='clzero'/> + <feature name='xsaveerptr'/> ++ <feature name='npt'/> ++ <feature name='lbrv'/> ++ <feature name='svm-lock'/> ++ <feature name='nrip-save'/> ++ <feature name='tsc-scale'/> ++ <feature name='vmcb-clean'/> ++ <feature name='flushbyasid'/> ++ <feature name='decodeassists'/> ++ <feature name='pause-filter'/> ++ <feature name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml +index a7f4fa3f01..f4d92cf034 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml +@@ -5,4 +5,5 @@ + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c2300c' edx='0x08000000'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> + <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x000014f6'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-enabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-enabled.xml +index 772456f947..910491c7f6 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-enabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-enabled.xml +@@ -6,4 +6,5 @@ + <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000007' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x000003f3' edx='0x26500800'/> + <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00001000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml +index 96fdea306f..9164987bbd 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml +@@ -15,5 +15,15 @@ + <feature policy='require' name='invtsc'/> + <feature policy='require' name='clzero'/> + <feature policy='require' name='xsaveerptr'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='lbrv'/> ++ <feature policy='require' name='svm-lock'/> ++ <feature policy='require' name='nrip-save'/> ++ <feature policy='require' name='tsc-scale'/> ++ <feature policy='require' name='vmcb-clean'/> ++ <feature policy='require' name='flushbyasid'/> ++ <feature policy='require' name='decodeassists'/> ++ <feature policy='require' name='pause-filter'/> ++ <feature policy='require' name='pfthreshold'/> + <feature policy='disable' name='rdtscp'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml +index 4fff74f3aa..2fa8861e44 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml +@@ -16,4 +16,14 @@ + <feature name='invtsc'/> + <feature name='clzero'/> + <feature name='xsaveerptr'/> ++ <feature name='npt'/> ++ <feature name='lbrv'/> ++ <feature name='svm-lock'/> ++ <feature name='nrip-save'/> ++ <feature name='tsc-scale'/> ++ <feature name='vmcb-clean'/> ++ <feature name='flushbyasid'/> ++ <feature name='decodeassists'/> ++ <feature name='pause-filter'/> ++ <feature name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-json.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-json.xml +index c4e34a0fa1..af1e7f2f32 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-json.xml +@@ -6,6 +6,8 @@ + <feature policy='require' name='hypervisor'/> + <feature policy='require' name='tsc_adjust'/> + <feature policy='require' name='cmp_legacy'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='nrip-save'/> + <feature policy='disable' name='monitor'/> + <feature policy='disable' name='rdtscp'/> + <feature policy='disable' name='svm'/> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-json.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-json.xml +index 7bf2d1b852..4450a40f61 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-json.xml +@@ -6,6 +6,8 @@ + <feature policy='require' name='hypervisor'/> + <feature policy='require' name='tsc_adjust'/> + <feature policy='require' name='cmp_legacy'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='nrip-save'/> + <feature policy='disable' name='monitor'/> + <feature policy='disable' name='svm'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-FX-8150-guest.xml b/tests/cputestdata/x86_64-cpuid-FX-8150-guest.xml +index 6bd032bbcb..ee34ea8547 100644 +--- a/tests/cputestdata/x86_64-cpuid-FX-8150-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-FX-8150-guest.xml +@@ -20,4 +20,14 @@ + <feature policy='require' name='perfctr_core'/> + <feature policy='require' name='perfctr_nb'/> + <feature policy='require' name='invtsc'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='lbrv'/> ++ <feature policy='require' name='svm-lock'/> ++ <feature policy='require' name='nrip-save'/> ++ <feature policy='require' name='tsc-scale'/> ++ <feature policy='require' name='vmcb-clean'/> ++ <feature policy='require' name='flushbyasid'/> ++ <feature policy='require' name='decodeassists'/> ++ <feature policy='require' name='pause-filter'/> ++ <feature policy='require' name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-FX-8150-host.xml b/tests/cputestdata/x86_64-cpuid-FX-8150-host.xml +index ec670c612e..75595c02af 100644 +--- a/tests/cputestdata/x86_64-cpuid-FX-8150-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-FX-8150-host.xml +@@ -21,4 +21,14 @@ + <feature name='perfctr_core'/> + <feature name='perfctr_nb'/> + <feature name='invtsc'/> ++ <feature name='npt'/> ++ <feature name='lbrv'/> ++ <feature name='svm-lock'/> ++ <feature name='nrip-save'/> ++ <feature name='tsc-scale'/> ++ <feature name='vmcb-clean'/> ++ <feature name='flushbyasid'/> ++ <feature name='decodeassists'/> ++ <feature name='pause-filter'/> ++ <feature name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml +index c26c9c7be3..25ef2d3314 100644 +--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml +@@ -5,4 +5,5 @@ + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c2300c' edx='0x00000000'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> + <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x000014f6'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-enabled.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-enabled.xml +index fcefcf73c8..9181c3a9fe 100644 +--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-enabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-enabled.xml +@@ -6,4 +6,5 @@ + <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000007' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x000003f3' edx='0x2e500800'/> + <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml +index 844b8b9d4f..08c574255e 100644 +--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml +@@ -15,4 +15,14 @@ + <feature policy='require' name='invtsc'/> + <feature policy='require' name='clzero'/> + <feature policy='require' name='xsaveerptr'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='lbrv'/> ++ <feature policy='require' name='svm-lock'/> ++ <feature policy='require' name='nrip-save'/> ++ <feature policy='require' name='tsc-scale'/> ++ <feature policy='require' name='vmcb-clean'/> ++ <feature policy='require' name='flushbyasid'/> ++ <feature policy='require' name='decodeassists'/> ++ <feature policy='require' name='pause-filter'/> ++ <feature policy='require' name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml +index 3d1b143eba..f1cddb6a19 100644 +--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml +@@ -16,4 +16,14 @@ + <feature name='invtsc'/> + <feature name='clzero'/> + <feature name='xsaveerptr'/> ++ <feature name='npt'/> ++ <feature name='lbrv'/> ++ <feature name='svm-lock'/> ++ <feature name='nrip-save'/> ++ <feature name='tsc-scale'/> ++ <feature name='vmcb-clean'/> ++ <feature name='flushbyasid'/> ++ <feature name='decodeassists'/> ++ <feature name='pause-filter'/> ++ <feature name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-json.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-json.xml +index d3003b6965..0fdd934c08 100644 +--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-json.xml +@@ -7,6 +7,8 @@ + <feature policy='require' name='tsc_adjust'/> + <feature policy='require' name='cmp_legacy'/> + <feature policy='require' name='virt-ssbd'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='nrip-save'/> + <feature policy='disable' name='monitor'/> + <feature policy='disable' name='svm'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-1352-guest.xml b/tests/cputestdata/x86_64-cpuid-Opteron-1352-guest.xml +index 652f1e4333..a52c4cd303 100644 +--- a/tests/cputestdata/x86_64-cpuid-Opteron-1352-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-1352-guest.xml +@@ -15,4 +15,7 @@ + <feature policy='require' name='osvw'/> + <feature policy='require' name='ibs'/> + <feature policy='require' name='invtsc'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='lbrv'/> ++ <feature policy='require' name='svm-lock'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-1352-host.xml b/tests/cputestdata/x86_64-cpuid-Opteron-1352-host.xml +index 399398eb3a..800b092f14 100644 +--- a/tests/cputestdata/x86_64-cpuid-Opteron-1352-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-1352-host.xml +@@ -16,4 +16,7 @@ + <feature name='osvw'/> + <feature name='ibs'/> + <feature name='invtsc'/> ++ <feature name='npt'/> ++ <feature name='lbrv'/> ++ <feature name='svm-lock'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-2350-disabled.xml b/tests/cputestdata/x86_64-cpuid-Opteron-2350-disabled.xml +index 8ec1b12582..3f6fe54055 100644 +--- a/tests/cputestdata/x86_64-cpuid-Opteron-2350-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-2350-disabled.xml +@@ -3,4 +3,5 @@ + <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000008' edx='0x10000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000408' edx='0x08000000'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-2350-enabled.xml b/tests/cputestdata/x86_64-cpuid-Opteron-2350-enabled.xml +index 913980f15f..5fd0d6066d 100644 +--- a/tests/cputestdata/x86_64-cpuid-Opteron-2350-enabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-2350-enabled.xml +@@ -2,4 +2,5 @@ + <cpudata arch='x86'> + <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x81a02001' edx='0x078bfbff'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x000003f7' edx='0xe6500800'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000001'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-2350-guest.xml b/tests/cputestdata/x86_64-cpuid-Opteron-2350-guest.xml +index 652f1e4333..a52c4cd303 100644 +--- a/tests/cputestdata/x86_64-cpuid-Opteron-2350-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-2350-guest.xml +@@ -15,4 +15,7 @@ + <feature policy='require' name='osvw'/> + <feature policy='require' name='ibs'/> + <feature policy='require' name='invtsc'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='lbrv'/> ++ <feature policy='require' name='svm-lock'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-2350-host.xml b/tests/cputestdata/x86_64-cpuid-Opteron-2350-host.xml +index 399398eb3a..800b092f14 100644 +--- a/tests/cputestdata/x86_64-cpuid-Opteron-2350-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-2350-host.xml +@@ -16,4 +16,7 @@ + <feature name='osvw'/> + <feature name='ibs'/> + <feature name='invtsc'/> ++ <feature name='npt'/> ++ <feature name='lbrv'/> ++ <feature name='svm-lock'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-2350-json.xml b/tests/cputestdata/x86_64-cpuid-Opteron-2350-json.xml +index 741757aeb2..d128553c13 100644 +--- a/tests/cputestdata/x86_64-cpuid-Opteron-2350-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-2350-json.xml +@@ -14,6 +14,7 @@ + <feature policy='require' name='cr8legacy'/> + <feature policy='require' name='3dnowprefetch'/> + <feature policy='require' name='osvw'/> ++ <feature policy='require' name='npt'/> + <feature policy='disable' name='monitor'/> + <feature policy='disable' name='rdtscp'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6234-disabled.xml b/tests/cputestdata/x86_64-cpuid-Opteron-6234-disabled.xml +index 88124d1745..4dcd74103b 100644 +--- a/tests/cputestdata/x86_64-cpuid-Opteron-6234-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6234-disabled.xml +@@ -3,4 +3,5 @@ + <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x08000008' edx='0x10000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c8b40c' edx='0x08000000'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x000014f6'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6234-enabled.xml b/tests/cputestdata/x86_64-cpuid-Opteron-6234-enabled.xml +index 38d716449d..890b5df060 100644 +--- a/tests/cputestdata/x86_64-cpuid-Opteron-6234-enabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6234-enabled.xml +@@ -4,4 +4,5 @@ + <cpuid eax_in='0x00000006' ecx_in='0x00' eax='0x00000004' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000002' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00010bf3' edx='0x26500800'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6234-guest.xml b/tests/cputestdata/x86_64-cpuid-Opteron-6234-guest.xml +index 6bd032bbcb..ee34ea8547 100644 +--- a/tests/cputestdata/x86_64-cpuid-Opteron-6234-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6234-guest.xml +@@ -20,4 +20,14 @@ + <feature policy='require' name='perfctr_core'/> + <feature policy='require' name='perfctr_nb'/> + <feature policy='require' name='invtsc'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='lbrv'/> ++ <feature policy='require' name='svm-lock'/> ++ <feature policy='require' name='nrip-save'/> ++ <feature policy='require' name='tsc-scale'/> ++ <feature policy='require' name='vmcb-clean'/> ++ <feature policy='require' name='flushbyasid'/> ++ <feature policy='require' name='decodeassists'/> ++ <feature policy='require' name='pause-filter'/> ++ <feature policy='require' name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6234-host.xml b/tests/cputestdata/x86_64-cpuid-Opteron-6234-host.xml +index ec670c612e..75595c02af 100644 +--- a/tests/cputestdata/x86_64-cpuid-Opteron-6234-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6234-host.xml +@@ -21,4 +21,14 @@ + <feature name='perfctr_core'/> + <feature name='perfctr_nb'/> + <feature name='invtsc'/> ++ <feature name='npt'/> ++ <feature name='lbrv'/> ++ <feature name='svm-lock'/> ++ <feature name='nrip-save'/> ++ <feature name='tsc-scale'/> ++ <feature name='vmcb-clean'/> ++ <feature name='flushbyasid'/> ++ <feature name='decodeassists'/> ++ <feature name='pause-filter'/> ++ <feature name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6234-json.xml b/tests/cputestdata/x86_64-cpuid-Opteron-6234-json.xml +index 2ad3c98a5a..abfc8db290 100644 +--- a/tests/cputestdata/x86_64-cpuid-Opteron-6234-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6234-json.xml +@@ -12,6 +12,8 @@ + <feature policy='require' name='cmp_legacy'/> + <feature policy='require' name='cr8legacy'/> + <feature policy='require' name='osvw'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='nrip-save'/> + <feature policy='disable' name='rdtscp'/> + <feature policy='disable' name='svm'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6282-guest.xml b/tests/cputestdata/x86_64-cpuid-Opteron-6282-guest.xml +index 6bd032bbcb..ee34ea8547 100644 +--- a/tests/cputestdata/x86_64-cpuid-Opteron-6282-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6282-guest.xml +@@ -20,4 +20,14 @@ + <feature policy='require' name='perfctr_core'/> + <feature policy='require' name='perfctr_nb'/> + <feature policy='require' name='invtsc'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='lbrv'/> ++ <feature policy='require' name='svm-lock'/> ++ <feature policy='require' name='nrip-save'/> ++ <feature policy='require' name='tsc-scale'/> ++ <feature policy='require' name='vmcb-clean'/> ++ <feature policy='require' name='flushbyasid'/> ++ <feature policy='require' name='decodeassists'/> ++ <feature policy='require' name='pause-filter'/> ++ <feature policy='require' name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Opteron-6282-host.xml b/tests/cputestdata/x86_64-cpuid-Opteron-6282-host.xml +index ec670c612e..75595c02af 100644 +--- a/tests/cputestdata/x86_64-cpuid-Opteron-6282-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Opteron-6282-host.xml +@@ -21,4 +21,14 @@ + <feature name='perfctr_core'/> + <feature name='perfctr_nb'/> + <feature name='invtsc'/> ++ <feature name='npt'/> ++ <feature name='lbrv'/> ++ <feature name='svm-lock'/> ++ <feature name='nrip-save'/> ++ <feature name='tsc-scale'/> ++ <feature name='vmcb-clean'/> ++ <feature name='flushbyasid'/> ++ <feature name='decodeassists'/> ++ <feature name='pause-filter'/> ++ <feature name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Phenom-B95-disabled.xml b/tests/cputestdata/x86_64-cpuid-Phenom-B95-disabled.xml +index d8d4e8a5f9..3910eb6e57 100644 +--- a/tests/cputestdata/x86_64-cpuid-Phenom-B95-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Phenom-B95-disabled.xml +@@ -3,4 +3,5 @@ + <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000008' edx='0x10000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x0000340c' edx='0x08000000'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Phenom-B95-enabled.xml b/tests/cputestdata/x86_64-cpuid-Phenom-B95-enabled.xml +index d15e625087..2a090a04d8 100644 +--- a/tests/cputestdata/x86_64-cpuid-Phenom-B95-enabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Phenom-B95-enabled.xml +@@ -2,4 +2,5 @@ + <cpudata arch='x86'> + <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x80a02001' edx='0x078bfbff'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x000003f3' edx='0xe6400800'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Phenom-B95-guest.xml b/tests/cputestdata/x86_64-cpuid-Phenom-B95-guest.xml +index d7a06108bc..ab0e99f97d 100644 +--- a/tests/cputestdata/x86_64-cpuid-Phenom-B95-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Phenom-B95-guest.xml +@@ -17,5 +17,9 @@ + <feature policy='require' name='skinit'/> + <feature policy='require' name='wdt'/> + <feature policy='require' name='invtsc'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='lbrv'/> ++ <feature policy='require' name='svm-lock'/> ++ <feature policy='require' name='nrip-save'/> + <feature policy='disable' name='nx'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Phenom-B95-host.xml b/tests/cputestdata/x86_64-cpuid-Phenom-B95-host.xml +index 127b047854..95875918c9 100644 +--- a/tests/cputestdata/x86_64-cpuid-Phenom-B95-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Phenom-B95-host.xml +@@ -28,4 +28,8 @@ + <feature name='skinit'/> + <feature name='wdt'/> + <feature name='invtsc'/> ++ <feature name='npt'/> ++ <feature name='lbrv'/> ++ <feature name='svm-lock'/> ++ <feature name='nrip-save'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Phenom-B95-json.xml b/tests/cputestdata/x86_64-cpuid-Phenom-B95-json.xml +index 7ce56ac8e7..d161709981 100644 +--- a/tests/cputestdata/x86_64-cpuid-Phenom-B95-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Phenom-B95-json.xml +@@ -13,6 +13,8 @@ + <feature policy='require' name='cr8legacy'/> + <feature policy='require' name='3dnowprefetch'/> + <feature policy='require' name='osvw'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='nrip-save'/> + <feature policy='disable' name='monitor'/> + <feature policy='disable' name='nx'/> + <feature policy='disable' name='rdtscp'/> +diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml +index 0358ecf478..a63cd5c4b4 100644 +--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml +@@ -6,4 +6,5 @@ + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c23008' edx='0x00000000'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> + <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x000014f6'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-enabled.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-enabled.xml +index a212679fba..f1a0ad3315 100644 +--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-enabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-enabled.xml +@@ -5,4 +5,5 @@ + <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x009c01ab' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000007' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x000003f7' edx='0x2e500800'/> ++ <cpuid eax_in='0x8000000a' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000009'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml +index 612e571609..0053913327 100644 +--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml +@@ -15,4 +15,14 @@ + <feature policy='require' name='invtsc'/> + <feature policy='require' name='clzero'/> + <feature policy='require' name='xsaveerptr'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='lbrv'/> ++ <feature policy='require' name='svm-lock'/> ++ <feature policy='require' name='nrip-save'/> ++ <feature policy='require' name='tsc-scale'/> ++ <feature policy='require' name='vmcb-clean'/> ++ <feature policy='require' name='flushbyasid'/> ++ <feature policy='require' name='decodeassists'/> ++ <feature policy='require' name='pause-filter'/> ++ <feature policy='require' name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml +index 7498d924e2..7acab0a999 100644 +--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml +@@ -16,4 +16,14 @@ + <feature name='invtsc'/> + <feature name='clzero'/> + <feature name='xsaveerptr'/> ++ <feature name='npt'/> ++ <feature name='lbrv'/> ++ <feature name='svm-lock'/> ++ <feature name='nrip-save'/> ++ <feature name='tsc-scale'/> ++ <feature name='vmcb-clean'/> ++ <feature name='flushbyasid'/> ++ <feature name='decodeassists'/> ++ <feature name='pause-filter'/> ++ <feature name='pfthreshold'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-json.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-json.xml +index 32064548c7..aecc335c1e 100644 +--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-json.xml +@@ -6,6 +6,8 @@ + <feature policy='require' name='hypervisor'/> + <feature policy='require' name='tsc_adjust'/> + <feature policy='require' name='cmp_legacy'/> ++ <feature policy='require' name='npt'/> ++ <feature policy='require' name='nrip-save'/> + <feature policy='disable' name='monitor'/> + <feature policy='disable' name='sha-ni'/> + </cpu> +diff --git a/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml +index d369fa827a..d3211e7a13 100644 +--- a/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml +@@ -43,6 +43,7 @@ + <feature policy='require' name='la57'/> + <feature policy='require' name='3dnowext'/> + <feature policy='require' name='3dnow'/> ++ <feature policy='require' name='npt'/> + <feature policy='disable' name='vme'/> + <feature policy='disable' name='fma'/> + <feature policy='disable' name='avx'/> +diff --git a/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml +index 444d90504e..756b28034e 100644 +--- a/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml +@@ -43,6 +43,7 @@ + <feature policy='require' name='la57'/> + <feature policy='require' name='3dnowext'/> + <feature policy='require' name='3dnow'/> ++ <feature policy='require' name='npt'/> + <feature policy='disable' name='vme'/> + <feature policy='disable' name='fma'/> + <feature policy='disable' name='avx'/> +diff --git a/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml +index 463f0db390..0aa8aa18be 100644 +--- a/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml +@@ -43,6 +43,7 @@ + <feature policy='require' name='la57'/> + <feature policy='require' name='3dnowext'/> + <feature policy='require' name='3dnow'/> ++ <feature policy='require' name='npt'/> + <feature policy='disable' name='vme'/> + <feature policy='disable' name='fma'/> + <feature policy='disable' name='avx'/> +@@ -57,6 +58,7 @@ + <feature policy='disable' name='3dnowprefetch'/> + <feature policy='disable' name='osvw'/> + <feature policy='disable' name='topoext'/> ++ <feature policy='disable' name='nrip-save'/> + </mode> + <mode name='custom' supported='yes'> + <model usable='yes'>qemu64</model> +diff --git a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml +index 5bfd065986..d6265ce243 100644 +--- a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml +@@ -43,6 +43,7 @@ + <feature policy='require' name='la57'/> + <feature policy='require' name='3dnowext'/> + <feature policy='require' name='3dnow'/> ++ <feature policy='require' name='npt'/> + <feature policy='disable' name='vme'/> + <feature policy='disable' name='fma'/> + <feature policy='disable' name='avx'/> +@@ -57,6 +58,7 @@ + <feature policy='disable' name='osvw'/> + <feature policy='disable' name='topoext'/> + <feature policy='disable' name='ibpb'/> ++ <feature policy='disable' name='nrip-save'/> + </mode> + <mode name='custom' supported='yes'> + <model usable='yes'>qemu64</model> +diff --git a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml +index c762b0b600..bcaf9afd6f 100644 +--- a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml +@@ -43,6 +43,7 @@ + <feature policy='require' name='la57'/> + <feature policy='require' name='3dnowext'/> + <feature policy='require' name='3dnow'/> ++ <feature policy='require' name='npt'/> + <feature policy='disable' name='vme'/> + <feature policy='disable' name='fma'/> + <feature policy='disable' name='avx'/> +@@ -57,6 +58,7 @@ + <feature policy='disable' name='osvw'/> + <feature policy='disable' name='topoext'/> + <feature policy='disable' name='ibpb'/> ++ <feature policy='disable' name='nrip-save'/> + </mode> + <mode name='custom' supported='yes'> + <model usable='yes'>qemu64</model> +diff --git a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml +index 0a4bb16a89..eb456dea28 100644 +--- a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml +@@ -43,6 +43,7 @@ + <feature policy='require' name='la57'/> + <feature policy='require' name='3dnowext'/> + <feature policy='require' name='3dnow'/> ++ <feature policy='require' name='npt'/> + <feature policy='disable' name='vme'/> + <feature policy='disable' name='fma'/> + <feature policy='disable' name='avx'/> +@@ -56,6 +57,7 @@ + <feature policy='disable' name='3dnowprefetch'/> + <feature policy='disable' name='osvw'/> + <feature policy='disable' name='topoext'/> ++ <feature policy='disable' name='nrip-save'/> + </mode> + <mode name='custom' supported='yes'> + <model usable='yes'>qemu64</model> +diff --git a/tests/qemuxml2argvdata/cpu-host-model-cmt.x86_64-4.0.0.args b/tests/qemuxml2argvdata/cpu-host-model-cmt.x86_64-4.0.0.args +index b44dc2ec48..6ee7bed18e 100644 +--- a/tests/qemuxml2argvdata/cpu-host-model-cmt.x86_64-4.0.0.args ++++ b/tests/qemuxml2argvdata/cpu-host-model-cmt.x86_64-4.0.0.args +@@ -14,9 +14,9 @@ QEMU_AUDIO_DRV=none \ + file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ + -machine pc-i440fx-4.0,accel=tcg,usb=off,dump-guest-core=off \ + -cpu EPYC,acpi=on,ss=on,hypervisor=on,erms=on,mpx=on,pcommit=on,clwb=on,pku=on,\ +-la57=on,3dnowext=on,3dnow=on,vme=off,fma=off,avx=off,f16c=off,rdrand=off,\ +-avx2=off,rdseed=off,sha-ni=off,xsavec=off,fxsr_opt=off,misalignsse=off,\ +-3dnowprefetch=off,osvw=off,topoext=off \ ++la57=on,3dnowext=on,3dnow=on,npt=on,vme=off,fma=off,avx=off,f16c=off,\ ++rdrand=off,avx2=off,rdseed=off,sha-ni=off,xsavec=off,fxsr_opt=off,\ ++misalignsse=off,3dnowprefetch=off,osvw=off,topoext=off,nrip-save=off \ + -m 214 \ + -overcommit mem-lock=off \ + -smp 6,sockets=6,cores=1,threads=1 \ +-- +2.29.2 + diff --git a/SOURCES/libvirt-cpu_map-Add-missing-x86-features-in-0x7-CPUID-leaf.patch b/SOURCES/libvirt-cpu_map-Add-missing-x86-features-in-0x7-CPUID-leaf.patch new file mode 100644 index 0000000..42bfd9e --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-missing-x86-features-in-0x7-CPUID-leaf.patch @@ -0,0 +1,107 @@ +From cff220056e78bad15a8addf9739f8a556b7a6ea2 Mon Sep 17 00:00:00 2001 +Message-Id: <cff220056e78bad15a8addf9739f8a556b7a6ea2@dist-git> +From: Jiri Denemark <jdenemar@redhat.com> +Date: Thu, 8 Oct 2020 18:01:21 +0200 +Subject: [PATCH] cpu_map: Add missing x86 features in 0x7 CPUID leaf +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> +(cherry picked from commit 6ea3bb19c6fed39429c95eb284487b849cb12e2a) + +https://bugzilla.redhat.com/show_bug.cgi?id=1861506 + +Conflicts: + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-enabled.xml + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-guest.xml + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-host.xml + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-json.xml + tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml + tests/domaincapsdata/qemu_5.1.0.x86_64.xml + - not present downstream + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Message-Id: <04da640b0fbbbcec9be63e552a3029f983bf879a.1602172344.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/cpu_map/x86_features.xml | 12 ++++++++++++ + .../x86_64-cpuid-Ice-Lake-Server-disabled.xml | 2 +- + .../x86_64-cpuid-Ice-Lake-Server-guest.xml | 1 + + .../x86_64-cpuid-Ice-Lake-Server-host.xml | 1 + + 4 files changed, 15 insertions(+), 1 deletion(-) + +diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml +index 8525ae0fa5..364e45fb32 100644 +--- a/src/cpu_map/x86_features.xml ++++ b/src/cpu_map/x86_features.xml +@@ -286,6 +286,9 @@ + <feature name='ospke'> + <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x00000010'/> + </feature> ++ <feature name='waitpkg'> ++ <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x00000020'/> ++ </feature> + <feature name='avx512vbmi2'> + <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x00000040'/> + </feature> +@@ -310,9 +313,18 @@ + <feature name='la57'> + <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x00010000'/> + </feature> ++ <feature name='rdpid'> ++ <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x00400000'/> ++ </feature> + <feature name='cldemote'> + <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x02000000'/> + </feature> ++ <feature name='movdiri'> ++ <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x08000000'/> ++ </feature> ++ <feature name='movdir64b'> ++ <cpuid eax_in='0x07' ecx_in='0x00' ecx='0x10000000'/> ++ </feature> + + <feature name='avx512-4vnniw'> + <cpuid eax_in='0x07' ecx_in='0x00' edx='0x00000004'/> +diff --git a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml +index 62c6bad612..ce65579bcc 100644 +--- a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml +@@ -1,7 +1,7 @@ + <!-- Features disabled by QEMU --> + <cpudata arch='x86'> + <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x0804c1fc' edx='0xb0600000'/> +- <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00000010' edx='0x00000000'/> ++ <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00400010' edx='0x00000000'/> + <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml +index 4676f3aa7d..9b75ace710 100644 +--- a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml +@@ -23,6 +23,7 @@ + <feature policy='require' name='avx512ifma'/> + <feature policy='require' name='sha-ni'/> + <feature policy='require' name='ospke'/> ++ <feature policy='require' name='rdpid'/> + <feature policy='require' name='stibp'/> + <feature policy='require' name='arch-capabilities'/> + <feature policy='require' name='xsaves'/> +diff --git a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml +index 35b9e39629..efbf9d363b 100644 +--- a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml +@@ -24,6 +24,7 @@ + <feature name='avx512ifma'/> + <feature name='sha-ni'/> + <feature name='ospke'/> ++ <feature name='rdpid'/> + <feature name='stibp'/> + <feature name='arch-capabilities'/> + <feature name='xsaves'/> +-- +2.29.2 + diff --git a/SOURCES/libvirt-cpu_map-Add-missing-x86-features-in-0x80000008-CPUID-leaf.patch b/SOURCES/libvirt-cpu_map-Add-missing-x86-features-in-0x80000008-CPUID-leaf.patch new file mode 100644 index 0000000..b7020fc --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-missing-x86-features-in-0x80000008-CPUID-leaf.patch @@ -0,0 +1,224 @@ +From 1d6a30efa98fc0cf39725792efae1a151797589f Mon Sep 17 00:00:00 2001 +Message-Id: <1d6a30efa98fc0cf39725792efae1a151797589f@dist-git> +From: Jiri Denemark <jdenemar@redhat.com> +Date: Thu, 8 Oct 2020 18:01:22 +0200 +Subject: [PATCH] cpu_map: Add missing x86 features in 0x80000008 CPUID leaf +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> +(cherry picked from commit 892b7c70f66abc511e1251382c9183493024f253) + +https://bugzilla.redhat.com/show_bug.cgi?id=1861506 + +Conflicts: + tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml + tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml + tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml + tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml + - commit df69263c26 (cpu_map: Request test files update when + adding x86 features) not backported + + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-disabled.xml + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-enabled.xml + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-guest.xml + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-host.xml + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-json.xml + tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml + tests/domaincapsdata/qemu_5.1.0.x86_64.xml + - not present downstream + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Message-Id: <27effeb5e12252982411796bd72e078d3afe49cb.1602172344.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/cpu_map/x86_features.xml | 6 ++++++ + tests/cputestdata/x86_64-cpuid-Cooperlake-enabled.xml | 2 +- + tests/cputestdata/x86_64-cpuid-Cooperlake-json.xml | 1 + + .../cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml | 1 + + tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml | 1 + + tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml | 1 + + .../x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml | 1 + + .../x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml | 1 + + .../x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml | 1 + + .../x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml | 1 + + .../x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml | 1 + + .../x86_64-cpuid-Hygon-C86-7185-32-core-host.xml | 1 + + .../x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml | 1 + + .../x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml | 1 + + .../x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml | 1 + + 15 files changed, 20 insertions(+), 1 deletion(-) + +diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml +index 364e45fb32..5265b2989b 100644 +--- a/src/cpu_map/x86_features.xml ++++ b/src/cpu_map/x86_features.xml +@@ -486,12 +486,18 @@ + <feature name='clzero'> + <cpuid eax_in='0x80000008' ebx='0x00000001'/> + </feature> ++ <feature name='xsaveerptr'> ++ <cpuid eax_in='0x80000008' ebx='0x00000004'/> ++ </feature> + <feature name='wbnoinvd'> + <cpuid eax_in='0x80000008' ebx='0x00000200'/> + </feature> + <feature name='ibpb'> + <cpuid eax_in='0x80000008' ebx='0x00001000'/> + </feature> ++ <feature name='amd-stibp'> ++ <cpuid eax_in='0x80000008' ebx='0x00008000'/> ++ </feature> + <feature name='amd-ssbd'> + <cpuid eax_in='0x80000008' ebx='0x01000000'/> + </feature> +diff --git a/tests/cputestdata/x86_64-cpuid-Cooperlake-enabled.xml b/tests/cputestdata/x86_64-cpuid-Cooperlake-enabled.xml +index 2d7f83c80f..1d91c3efa8 100644 +--- a/tests/cputestdata/x86_64-cpuid-Cooperlake-enabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Cooperlake-enabled.xml +@@ -6,6 +6,6 @@ + <cpuid eax_in='0x00000007' ecx_in='0x01' eax='0x00000020' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x0000000f' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000121' edx='0x2c100800'/> +- <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x01001000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x01009000' ecx='0x00000000' edx='0x00000000'/> + <msr index='0x10a' edx='0x00000000' eax='0x000001eb'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Cooperlake-json.xml b/tests/cputestdata/x86_64-cpuid-Cooperlake-json.xml +index fb319d547c..c89e0e5350 100644 +--- a/tests/cputestdata/x86_64-cpuid-Cooperlake-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Cooperlake-json.xml +@@ -10,6 +10,7 @@ + <feature policy='require' name='md-clear'/> + <feature policy='require' name='xsaves'/> + <feature policy='require' name='ibpb'/> ++ <feature policy='require' name='amd-stibp'/> + <feature policy='require' name='amd-ssbd'/> + <feature policy='require' name='tsx-ctrl'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml +index 747d725acf..c26c9c7be3 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-disabled.xml +@@ -4,4 +4,5 @@ + <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000008' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c2300c' edx='0x00000000'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> ++ <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml +index b75196aac5..612e571609 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-guest.xml +@@ -14,4 +14,5 @@ + <feature policy='require' name='perfctr_nb'/> + <feature policy='require' name='invtsc'/> + <feature policy='require' name='clzero'/> ++ <feature policy='require' name='xsaveerptr'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml +index fd84b526db..7498d924e2 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-host.xml +@@ -15,4 +15,5 @@ + <feature name='perfctr_nb'/> + <feature name='invtsc'/> + <feature name='clzero'/> ++ <feature name='xsaveerptr'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml +index af43fca98d..a7f4fa3f01 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-disabled.xml +@@ -4,4 +4,5 @@ + <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000008' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c2300c' edx='0x08000000'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> ++ <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml +index 5044c8cc35..96fdea306f 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-guest.xml +@@ -14,5 +14,6 @@ + <feature policy='require' name='perfctr_nb'/> + <feature policy='require' name='invtsc'/> + <feature policy='require' name='clzero'/> ++ <feature policy='require' name='xsaveerptr'/> + <feature policy='disable' name='rdtscp'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml +index d7d5ce88d9..4fff74f3aa 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7601-32-Core-ibpb-host.xml +@@ -15,4 +15,5 @@ + <feature name='perfctr_nb'/> + <feature name='invtsc'/> + <feature name='clzero'/> ++ <feature name='xsaveerptr'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml +index 747d725acf..c26c9c7be3 100644 +--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-disabled.xml +@@ -4,4 +4,5 @@ + <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000008' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c2300c' edx='0x00000000'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> ++ <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml +index 75c71233c6..844b8b9d4f 100644 +--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-guest.xml +@@ -14,4 +14,5 @@ + <feature policy='require' name='perfctr_nb'/> + <feature policy='require' name='invtsc'/> + <feature policy='require' name='clzero'/> ++ <feature policy='require' name='xsaveerptr'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml +index 82f28067c4..3d1b143eba 100644 +--- a/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Hygon-C86-7185-32-core-host.xml +@@ -15,4 +15,5 @@ + <feature name='perfctr_nb'/> + <feature name='invtsc'/> + <feature name='clzero'/> ++ <feature name='xsaveerptr'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml +index b085050618..0358ecf478 100644 +--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-disabled.xml +@@ -5,4 +5,5 @@ + <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x00000008' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> + <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x01c23008' edx='0x00000000'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> ++ <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000005' ecx='0x00000000' edx='0x00000000'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml +index b75196aac5..612e571609 100644 +--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-guest.xml +@@ -14,4 +14,5 @@ + <feature policy='require' name='perfctr_nb'/> + <feature policy='require' name='invtsc'/> + <feature policy='require' name='clzero'/> ++ <feature policy='require' name='xsaveerptr'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml +index fd84b526db..7498d924e2 100644 +--- a/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Ryzen-7-1800X-Eight-Core-host.xml +@@ -15,4 +15,5 @@ + <feature name='perfctr_nb'/> + <feature name='invtsc'/> + <feature name='clzero'/> ++ <feature name='xsaveerptr'/> + </cpu> +-- +2.29.2 + diff --git a/SOURCES/libvirt-cpu_map-Add-support-for-core-capability-CPU-feature.patch b/SOURCES/libvirt-cpu_map-Add-support-for-core-capability-CPU-feature.patch new file mode 100644 index 0000000..0140b50 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-support-for-core-capability-CPU-feature.patch @@ -0,0 +1,76 @@ +From 287c112945dda0837c31348dc3c07ad7ed19596f Mon Sep 17 00:00:00 2001 +Message-Id: <287c112945dda0837c31348dc3c07ad7ed19596f@dist-git> +From: Tim Wiederhake <twiederh@redhat.com> +Date: Fri, 15 Jan 2021 15:17:20 +0100 +Subject: [PATCH] cpu_map: Add support for core-capability CPU feature + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +(cherry picked from commit e06dd56032acf904da1aedfc097fa0cae7cb0b0f) + +https://bugzilla.redhat.com/show_bug.cgi?id=1537734 + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Message-Id: <20210115141722.14986-5-twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/cpu_map/x86_features.xml | 3 +++ + tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml | 2 +- + tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml | 1 + + tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml | 1 + + 4 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml +index 70e1c7b3fc..f8c0b9046c 100644 +--- a/src/cpu_map/x86_features.xml ++++ b/src/cpu_map/x86_features.xml +@@ -350,6 +350,9 @@ + <feature name='arch-capabilities'> <!-- arch_capabilities, arch-facilities --> + <cpuid eax_in='0x07' ecx_in='0x00' edx='0x20000000'/> + </feature> ++ <feature name='core-capability'> ++ <cpuid eax_in='0x07' ecx_in='0x00' edx='0x40000000'/> ++ </feature> + <feature name='ssbd'> + <cpuid eax_in='0x07' ecx_in='0x00' edx='0x80000000'/> + </feature> +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml +index 842c7b4a2a..50e8084140 100644 +--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml +@@ -1,7 +1,7 @@ + <!-- Features disabled by QEMU --> + <cpudata arch='x86'> + <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x080041dc' edx='0xb0600000'/> +- <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00000020' edx='0x00000000'/> ++ <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00000020' edx='0x40000000'/> + <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> + <msr index='0x10a' edx='0x00000000' eax='0x00000100'/> +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml +index 0f3e2e506e..4ad95f06b4 100644 +--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml +@@ -37,6 +37,7 @@ + <feature policy='require' name='md-clear'/> + <feature policy='require' name='stibp'/> + <feature policy='require' name='arch-capabilities'/> ++ <feature policy='require' name='core-capability'/> + <feature policy='require' name='ssbd'/> + <feature policy='require' name='xsaveopt'/> + <feature policy='require' name='xsavec'/> +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml +index 3bd009c1da..cc2b208e6a 100644 +--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml +@@ -47,6 +47,7 @@ + <feature name='md-clear'/> + <feature name='stibp'/> + <feature name='arch-capabilities'/> ++ <feature name='core-capability'/> + <feature name='ssbd'/> + <feature name='xsaveopt'/> + <feature name='xsavec'/> +-- +2.30.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-support-for-fsrm-CPU-feature.patch b/SOURCES/libvirt-cpu_map-Add-support-for-fsrm-CPU-feature.patch new file mode 100644 index 0000000..c6bd8ab --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-support-for-fsrm-CPU-feature.patch @@ -0,0 +1,76 @@ +From 7de3eaba72cecf596c732d12485e4f1a6115bf2f Mon Sep 17 00:00:00 2001 +Message-Id: <7de3eaba72cecf596c732d12485e4f1a6115bf2f@dist-git> +From: Tim Wiederhake <twiederh@redhat.com> +Date: Fri, 15 Jan 2021 15:17:19 +0100 +Subject: [PATCH] cpu_map: Add support for fsrm CPU feature + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +(cherry picked from commit 8c5c660b99101544d8cfcb8edbe48688c04bee25) + +https://bugzilla.redhat.com/show_bug.cgi?id=1537734 + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Message-Id: <20210115141722.14986-4-twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/cpu_map/x86_features.xml | 3 +++ + tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml | 2 +- + tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml | 1 + + tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml | 1 + + 4 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml +index 30d1375437..70e1c7b3fc 100644 +--- a/src/cpu_map/x86_features.xml ++++ b/src/cpu_map/x86_features.xml +@@ -332,6 +332,9 @@ + <feature name='avx512-4fmaps'> + <cpuid eax_in='0x07' ecx_in='0x00' edx='0x00000008'/> + </feature> ++ <feature name='fsrm'> ++ <cpuid eax_in='0x07' ecx_in='0x00' edx='0x00000010'/> ++ </feature> + <feature name='md-clear'> <!-- md_clear --> + <cpuid eax_in='0x07' ecx_in='0x00' edx='0x00000400'/> + </feature> +diff --git a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml +index ce65579bcc..33bd1013f0 100644 +--- a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-disabled.xml +@@ -1,7 +1,7 @@ + <!-- Features disabled by QEMU --> + <cpudata arch='x86'> + <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x0804c1fc' edx='0xb0600000'/> +- <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00400010' edx='0x00000000'/> ++ <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00400010' edx='0x00000010'/> + <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml +index 9b75ace710..3a71b28cfb 100644 +--- a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-guest.xml +@@ -24,6 +24,7 @@ + <feature policy='require' name='sha-ni'/> + <feature policy='require' name='ospke'/> + <feature policy='require' name='rdpid'/> ++ <feature policy='require' name='fsrm'/> + <feature policy='require' name='stibp'/> + <feature policy='require' name='arch-capabilities'/> + <feature policy='require' name='xsaves'/> +diff --git a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml +index efbf9d363b..1582de0422 100644 +--- a/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Ice-Lake-Server-host.xml +@@ -25,6 +25,7 @@ + <feature name='sha-ni'/> + <feature name='ospke'/> + <feature name='rdpid'/> ++ <feature name='fsrm'/> + <feature name='stibp'/> + <feature name='arch-capabilities'/> + <feature name='xsaves'/> +-- +2.30.0 + diff --git a/SOURCES/libvirt-cpu_map-Add-support-for-split-lock-detect-CPU-feature.patch b/SOURCES/libvirt-cpu_map-Add-support-for-split-lock-detect-CPU-feature.patch new file mode 100644 index 0000000..9eee928 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Add-support-for-split-lock-detect-CPU-feature.patch @@ -0,0 +1,72 @@ +From 4b6dd39819e82b0775e0f324b0b4efa537882878 Mon Sep 17 00:00:00 2001 +Message-Id: <4b6dd39819e82b0775e0f324b0b4efa537882878@dist-git> +From: Tim Wiederhake <twiederh@redhat.com> +Date: Fri, 15 Jan 2021 15:17:21 +0100 +Subject: [PATCH] cpu_map: Add support for split-lock-detect CPU feature + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +(cherry picked from commit 13db542cf3099f7955438e208dbe4b2b4e58067e) + +https://bugzilla.redhat.com/show_bug.cgi?id=1537734 + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Message-Id: <20210115141722.14986-6-twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/cpu_map/x86_features.xml | 5 +++++ + tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml | 1 + + tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml | 1 + + tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml | 1 + + 4 files changed, 8 insertions(+) + +diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml +index f8c0b9046c..83d8e641a8 100644 +--- a/src/cpu_map/x86_features.xml ++++ b/src/cpu_map/x86_features.xml +@@ -574,4 +574,9 @@ + <feature name='taa-no'> + <msr index='0x10a' edx='0x00000000' eax='0x00000100'/> + </feature> ++ ++ <!-- IA32_CORE_CAPABILITIES features --> ++ <feature name='split-lock-detect'> ++ <msr index='0xcf' edx='0x00000000' eax='0x00000020'/> ++ </feature> + </cpus> +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml +index 50e8084140..81ffa7bfd3 100644 +--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml +@@ -4,5 +4,6 @@ + <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00000020' edx='0x40000000'/> + <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/> + <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> ++ <msr index='0xcf' edx='0x00000000' eax='0x00000020'/> + <msr index='0x10a' edx='0x00000000' eax='0x00000100'/> + </cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml +index 4ad95f06b4..2eeff136c4 100644 +--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml +@@ -53,6 +53,7 @@ + <feature policy='require' name='mds-no'/> + <feature policy='require' name='pschange-mc-no'/> + <feature policy='require' name='taa-no'/> ++ <feature policy='require' name='split-lock-detect'/> + <feature policy='disable' name='avx'/> + <feature policy='disable' name='f16c'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml +index cc2b208e6a..b3e9d5c1ff 100644 +--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml +@@ -64,4 +64,5 @@ + <feature name='mds-no'/> + <feature name='pschange-mc-no'/> + <feature name='taa-no'/> ++ <feature name='split-lock-detect'/> + </cpu> +-- +2.30.0 + diff --git a/SOURCES/libvirt-cpu_map-Define-and-enable-Snowridge-model.patch b/SOURCES/libvirt-cpu_map-Define-and-enable-Snowridge-model.patch new file mode 100644 index 0000000..6a04845 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Define-and-enable-Snowridge-model.patch @@ -0,0 +1,373 @@ +From b177f66b37d0c64216ec579a5211461609a96ea8 Mon Sep 17 00:00:00 2001 +Message-Id: <b177f66b37d0c64216ec579a5211461609a96ea8@dist-git> +From: Tim Wiederhake <twiederh@redhat.com> +Date: Fri, 15 Jan 2021 15:17:22 +0100 +Subject: [PATCH] cpu_map: Define and enable Snowridge model + +Due to missing pdpe1gb support in the host CPU data, the CPU is still +incorrectly detected as Westmere-IBRS for host capabilities because we +don't have the option to disable features included in the base model +there. + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +(cherry picked from commit f0a5cf4b8a8b5a68348df5e8b197f30dd90b3c34) + +https://bugzilla.redhat.com/show_bug.cgi?id=1537734 + +Conflicts: +- src/cpu_map/index.xml: Context +- src/cpu_map/meson.build: Not present downstream +- tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml: Not present downstream +- tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml: Not present downstream +- tests/domaincapsdata/qemu_5.1.0.x86_64.xml: Not present downstream +- tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml: Not present downstream +- tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml: Not present downstream +- tests/domaincapsdata/qemu_5.2.0.x86_64.xml: Not present downstream + +Additions: +- src/cpu_map/Makefile.inc.am: Replaces upstream change of "meson.build" + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Message-Id: <20210115141722.14986-7-twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/cpu_map/Makefile.inc.am | 1 + + src/cpu_map/index.xml | 1 + + src/cpu_map/x86_Snowridge.xml | 71 +++++++++++++++++++ + .../x86_64-cpuid-Atom-P5362-guest.xml | 28 ++------ + .../x86_64-cpuid-Atom-P5362-json.xml | 26 ++----- + .../domaincapsdata/qemu_4.1.0-q35.x86_64.xml | 1 + + .../domaincapsdata/qemu_4.1.0-tcg.x86_64.xml | 1 + + tests/domaincapsdata/qemu_4.1.0.x86_64.xml | 1 + + .../domaincapsdata/qemu_4.2.0-q35.x86_64.xml | 1 + + .../domaincapsdata/qemu_4.2.0-tcg.x86_64.xml | 1 + + tests/domaincapsdata/qemu_4.2.0.x86_64.xml | 1 + + .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml | 1 + + .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml | 1 + + tests/domaincapsdata/qemu_5.0.0.x86_64.xml | 1 + + 14 files changed, 92 insertions(+), 44 deletions(-) + create mode 100644 src/cpu_map/x86_Snowridge.xml + +diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am +index aad4b410f9..1dd78c6715 100644 +--- a/src/cpu_map/Makefile.inc.am ++++ b/src/cpu_map/Makefile.inc.am +@@ -67,6 +67,7 @@ cpumap_DATA = \ + cpu_map/x86_Skylake-Server.xml \ + cpu_map/x86_Skylake-Server-IBRS.xml \ + cpu_map/x86_Skylake-Server-noTSX-IBRS.xml \ ++ cpu_map/x86_Snowridge.xml \ + cpu_map/x86_Westmere.xml \ + cpu_map/x86_Westmere-IBRS.xml \ + $(NULL) +diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml +index 633b017a93..2f58261e6d 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -55,6 +55,7 @@ + <include filename="x86_Icelake-Server.xml"/> + <include filename="x86_Icelake-Server-noTSX.xml"/> + <include filename="x86_Cooperlake.xml"/> ++ <include filename='x86_Snowridge.xml'/> + + <!-- AMD CPUs --> + <include filename="x86_athlon.xml"/> +diff --git a/src/cpu_map/x86_Snowridge.xml b/src/cpu_map/x86_Snowridge.xml +new file mode 100644 +index 0000000000..383a24d367 +--- /dev/null ++++ b/src/cpu_map/x86_Snowridge.xml +@@ -0,0 +1,71 @@ ++<cpus> ++ <model name='Snowridge'> ++ <decode host='on' guest='on'/> ++ <signature family='6' model='134'/> <!-- 080665 --> ++ <vendor name='Intel'/> ++ <feature name='3dnowprefetch'/> ++ <feature name='aes'/> ++ <feature name='apic'/> ++ <feature name='arat'/> ++ <feature name='arch-capabilities'/> ++ <feature name='cldemote'/> ++ <feature name='clflush'/> ++ <feature name='clflushopt'/> ++ <feature name='clwb'/> ++ <feature name='cmov'/> ++ <feature name='core-capability'/> ++ <feature name='cx16'/> ++ <feature name='cx8'/> ++ <feature name='de'/> ++ <feature name='erms'/> ++ <feature name='fpu'/> ++ <feature name='fsgsbase'/> ++ <feature name='fxsr'/> ++ <feature name='gfni'/> ++ <feature name='lahf_lm'/> ++ <feature name='lm'/> ++ <feature name='mca'/> ++ <feature name='mce'/> ++ <feature name='mmx'/> ++ <feature name='movbe'/> ++ <feature name='movdir64b'/> ++ <feature name='movdiri'/> ++ <feature name='msr'/> ++ <feature name='mtrr'/> ++ <feature name='nx'/> ++ <feature name='pae'/> ++ <feature name='pat'/> ++ <feature name='pclmuldq'/> ++ <feature name='pdpe1gb'/> ++ <feature name='pge'/> ++ <feature name='pni'/> ++ <feature name='popcnt'/> ++ <feature name='pse'/> ++ <feature name='pse36'/> ++ <feature name='rdrand'/> ++ <feature name='rdseed'/> ++ <feature name='rdtscp'/> ++ <feature name='sep'/> ++ <feature name='sha-ni'/> ++ <feature name='smap'/> ++ <feature name='smep'/> ++ <feature name='spec-ctrl'/> ++ <feature name='split-lock-detect'/> ++ <feature name='ssbd'/> ++ <feature name='sse'/> ++ <feature name='sse2'/> ++ <feature name='sse4.1'/> ++ <feature name='sse4.2'/> ++ <feature name='ssse3'/> ++ <feature name='syscall'/> ++ <feature name='tsc'/> ++ <feature name='tsc-deadline'/> ++ <feature name='umip'/> ++ <feature name='vme'/> ++ <feature name='x2apic'/> ++ <feature name='xgetbv1'/> ++ <feature name='xsave'/> ++ <feature name='xsavec'/> ++ <feature name='xsaveopt'/> ++ </model> ++</cpus> +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml +index 2eeff136c4..f28e70b9e0 100644 +--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml +@@ -1,5 +1,5 @@ + <cpu mode='custom' match='exact'> +- <model fallback='forbid'>IvyBridge-IBRS</model> ++ <model fallback='forbid'>Snowridge</model> + <vendor>Intel</vendor> + <feature policy='require' name='ds'/> + <feature policy='require' name='acpi'/> +@@ -16,36 +16,17 @@ + <feature policy='require' name='tm2'/> + <feature policy='require' name='xtpr'/> + <feature policy='require' name='pdcm'/> +- <feature policy='require' name='movbe'/> + <feature policy='require' name='osxsave'/> +- <feature policy='require' name='arat'/> + <feature policy='require' name='tsc_adjust'/> + <feature policy='require' name='cmt'/> +- <feature policy='require' name='rdseed'/> +- <feature policy='require' name='smap'/> +- <feature policy='require' name='clflushopt'/> +- <feature policy='require' name='clwb'/> + <feature policy='require' name='intel-pt'/> +- <feature policy='require' name='sha-ni'/> +- <feature policy='require' name='umip'/> + <feature policy='require' name='waitpkg'/> +- <feature policy='require' name='gfni'/> + <feature policy='require' name='rdpid'/> +- <feature policy='require' name='cldemote'/> +- <feature policy='require' name='movdiri'/> +- <feature policy='require' name='movdir64b'/> + <feature policy='require' name='md-clear'/> + <feature policy='require' name='stibp'/> +- <feature policy='require' name='arch-capabilities'/> +- <feature policy='require' name='core-capability'/> +- <feature policy='require' name='ssbd'/> +- <feature policy='require' name='xsaveopt'/> +- <feature policy='require' name='xsavec'/> +- <feature policy='require' name='xgetbv1'/> + <feature policy='require' name='xsaves'/> + <feature policy='require' name='mbm_total'/> + <feature policy='require' name='mbm_local'/> +- <feature policy='require' name='3dnowprefetch'/> + <feature policy='require' name='invtsc'/> + <feature policy='require' name='rdctl-no'/> + <feature policy='require' name='ibrs-all'/> +@@ -53,7 +34,8 @@ + <feature policy='require' name='mds-no'/> + <feature policy='require' name='pschange-mc-no'/> + <feature policy='require' name='taa-no'/> +- <feature policy='require' name='split-lock-detect'/> +- <feature policy='disable' name='avx'/> +- <feature policy='disable' name='f16c'/> ++ <feature policy='disable' name='mpx'/> ++ <feature policy='disable' name='core-capability'/> ++ <feature policy='disable' name='pdpe1gb'/> ++ <feature policy='disable' name='split-lock-detect'/> + </cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml +index ca685d2f80..bbe0919706 100644 +--- a/tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml +@@ -1,33 +1,15 @@ + <cpu mode='custom' match='exact'> +- <model fallback='forbid'>IvyBridge-IBRS</model> ++ <model fallback='forbid'>Snowridge</model> + <vendor>Intel</vendor> + <feature policy='require' name='ss'/> + <feature policy='require' name='vmx'/> + <feature policy='require' name='pdcm'/> +- <feature policy='require' name='movbe'/> + <feature policy='require' name='hypervisor'/> +- <feature policy='require' name='arat'/> + <feature policy='require' name='tsc_adjust'/> +- <feature policy='require' name='rdseed'/> +- <feature policy='require' name='smap'/> +- <feature policy='require' name='clflushopt'/> +- <feature policy='require' name='clwb'/> +- <feature policy='require' name='sha-ni'/> +- <feature policy='require' name='umip'/> +- <feature policy='require' name='gfni'/> + <feature policy='require' name='rdpid'/> +- <feature policy='require' name='cldemote'/> +- <feature policy='require' name='movdiri'/> +- <feature policy='require' name='movdir64b'/> + <feature policy='require' name='md-clear'/> + <feature policy='require' name='stibp'/> +- <feature policy='require' name='arch-capabilities'/> +- <feature policy='require' name='ssbd'/> +- <feature policy='require' name='xsaveopt'/> +- <feature policy='require' name='xsavec'/> +- <feature policy='require' name='xgetbv1'/> + <feature policy='require' name='xsaves'/> +- <feature policy='require' name='3dnowprefetch'/> + <feature policy='require' name='ibpb'/> + <feature policy='require' name='amd-stibp'/> + <feature policy='require' name='amd-ssbd'/> +@@ -36,6 +18,8 @@ + <feature policy='require' name='skip-l1dfl-vmentry'/> + <feature policy='require' name='mds-no'/> + <feature policy='require' name='pschange-mc-no'/> +- <feature policy='disable' name='avx'/> +- <feature policy='disable' name='f16c'/> ++ <feature policy='disable' name='mpx'/> ++ <feature policy='disable' name='core-capability'/> ++ <feature policy='disable' name='pdpe1gb'/> ++ <feature policy='disable' name='split-lock-detect'/> + </cpu> +diff --git a/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml +index f4ddb66e38..228acde33b 100644 +--- a/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml +@@ -63,6 +63,7 @@ + <model usable='no'>athlon</model> + <model usable='yes'>Westmere-IBRS</model> + <model usable='yes'>Westmere</model> ++ <model usable='no'>Snowridge</model> + <model usable='no'>Skylake-Server-IBRS</model> + <model usable='no'>Skylake-Server</model> + <model usable='yes'>Skylake-Client-IBRS</model> +diff --git a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml +index d6265ce243..bda1aba8ed 100644 +--- a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml +@@ -75,6 +75,7 @@ + <model usable='yes'>athlon</model> + <model usable='no'>Westmere-IBRS</model> + <model usable='no'>Westmere</model> ++ <model usable='no'>Snowridge</model> + <model usable='no'>Skylake-Server-IBRS</model> + <model usable='no'>Skylake-Server</model> + <model usable='no'>Skylake-Client-IBRS</model> +diff --git a/tests/domaincapsdata/qemu_4.1.0.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0.x86_64.xml +index bcc8bbcc7a..bb53138712 100644 +--- a/tests/domaincapsdata/qemu_4.1.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.1.0.x86_64.xml +@@ -62,6 +62,7 @@ + <model usable='no'>athlon</model> + <model usable='yes'>Westmere-IBRS</model> + <model usable='yes'>Westmere</model> ++ <model usable='no'>Snowridge</model> + <model usable='no'>Skylake-Server-IBRS</model> + <model usable='no'>Skylake-Server</model> + <model usable='yes'>Skylake-Client-IBRS</model> +diff --git a/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml +index 4d9616cb69..0a3f3ef564 100644 +--- a/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml +@@ -64,6 +64,7 @@ + <model usable='no'>athlon</model> + <model usable='yes'>Westmere-IBRS</model> + <model usable='yes'>Westmere</model> ++ <model usable='no'>Snowridge</model> + <model usable='no'>Skylake-Server-noTSX-IBRS</model> + <model usable='no'>Skylake-Server-IBRS</model> + <model usable='no'>Skylake-Server</model> +diff --git a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml +index bcaf9afd6f..e64b647f51 100644 +--- a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml +@@ -75,6 +75,7 @@ + <model usable='yes'>athlon</model> + <model usable='no'>Westmere-IBRS</model> + <model usable='no'>Westmere</model> ++ <model usable='no'>Snowridge</model> + <model usable='no'>Skylake-Server-noTSX-IBRS</model> + <model usable='no'>Skylake-Server-IBRS</model> + <model usable='no'>Skylake-Server</model> +diff --git a/tests/domaincapsdata/qemu_4.2.0.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0.x86_64.xml +index 5210c917aa..5525758a48 100644 +--- a/tests/domaincapsdata/qemu_4.2.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_4.2.0.x86_64.xml +@@ -63,6 +63,7 @@ + <model usable='no'>athlon</model> + <model usable='yes'>Westmere-IBRS</model> + <model usable='yes'>Westmere</model> ++ <model usable='no'>Snowridge</model> + <model usable='no'>Skylake-Server-noTSX-IBRS</model> + <model usable='no'>Skylake-Server-IBRS</model> + <model usable='no'>Skylake-Server</model> +diff --git a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml +index b2a7087a0e..4cb4bf6cce 100644 +--- a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml +@@ -64,6 +64,7 @@ + <model usable='no'>athlon</model> + <model usable='yes'>Westmere-IBRS</model> + <model usable='yes'>Westmere</model> ++ <model usable='no'>Snowridge</model> + <model usable='no'>Skylake-Server-noTSX-IBRS</model> + <model usable='no'>Skylake-Server-IBRS</model> + <model usable='no'>Skylake-Server</model> +diff --git a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml +index 39b11fb634..b5986404ae 100644 +--- a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml +@@ -74,6 +74,7 @@ + <model usable='yes'>athlon</model> + <model usable='no'>Westmere-IBRS</model> + <model usable='yes'>Westmere</model> ++ <model usable='no'>Snowridge</model> + <model usable='no'>Skylake-Server-noTSX-IBRS</model> + <model usable='no'>Skylake-Server-IBRS</model> + <model usable='no'>Skylake-Server</model> +diff --git a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml +index 3a1ee23302..0297ce600b 100644 +--- a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml +@@ -63,6 +63,7 @@ + <model usable='no'>athlon</model> + <model usable='yes'>Westmere-IBRS</model> + <model usable='yes'>Westmere</model> ++ <model usable='no'>Snowridge</model> + <model usable='no'>Skylake-Server-noTSX-IBRS</model> + <model usable='no'>Skylake-Server-IBRS</model> + <model usable='no'>Skylake-Server</model> +-- +2.30.0 + diff --git a/SOURCES/libvirt-cpu_map-Defined-and-enable-EPYC-Rome-model.patch b/SOURCES/libvirt-cpu_map-Defined-and-enable-EPYC-Rome-model.patch new file mode 100644 index 0000000..0e6323a --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Defined-and-enable-EPYC-Rome-model.patch @@ -0,0 +1,310 @@ +From f441299f1b589a60199156a217c5f49fc9de954d Mon Sep 17 00:00:00 2001 +Message-Id: <f441299f1b589a60199156a217c5f49fc9de954d@dist-git> +From: Markus Schade <markus.schade@hetzner.com> +Date: Thu, 8 Oct 2020 18:01:25 +0200 +Subject: [PATCH] cpu_map: Defined and enable EPYC-Rome model +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Markus Schade <markus.schade@hetzner.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +(cherry picked from commit f941639f86f4bc66c106eb1291f1b58cf9e24680) + +https://bugzilla.redhat.com/show_bug.cgi?id=1861506 + +Conflicts: + src/cpu_map/meson.build + - the corresponding change was applied to Makefile.inc.am as + downstream still uses autotools + + tests/cputest.c + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-host.xml + - test data for Ryzen 9 3900X are not present downstream + + tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml + tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml + tests/domaincapsdata/qemu_5.1.0.x86_64.xml + tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml + tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml + tests/domaincapsdata/qemu_5.2.0.x86_64.xml + - not present downstream + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Message-Id: <bc87b8a0b0c408f380792eaf63ff07551185d3a5.1602172344.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/cpu_map/Makefile.inc.am | 1 + + src/cpu_map/index.xml | 1 + + src/cpu_map/x86_EPYC-Rome.xml | 84 +++++++++++++++++++ + .../x86_64-cpuid-EPYC-7502-32-Core-guest.xml | 12 +-- + .../x86_64-cpuid-EPYC-7502-32-Core-host.xml | 12 +-- + .../x86_64-cpuid-EPYC-7502-32-Core-json.xml | 12 +-- + .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml | 1 + + .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml | 1 + + tests/domaincapsdata/qemu_5.0.0.x86_64.xml | 1 + + 9 files changed, 92 insertions(+), 33 deletions(-) + create mode 100644 src/cpu_map/x86_EPYC-Rome.xml + +diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am +index b949cb0bea..aad4b410f9 100644 +--- a/src/cpu_map/Makefile.inc.am ++++ b/src/cpu_map/Makefile.inc.am +@@ -30,6 +30,7 @@ cpumap_DATA = \ + cpu_map/x86_Dhyana.xml \ + cpu_map/x86_EPYC.xml \ + cpu_map/x86_EPYC-IBPB.xml \ ++ cpu_map/x86_EPYC-Rome.xml \ + cpu_map/x86_Haswell.xml \ + cpu_map/x86_Haswell-IBRS.xml \ + cpu_map/x86_Haswell-noTSX.xml \ +diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml +index ff1da2e677..633b017a93 100644 +--- a/src/cpu_map/index.xml ++++ b/src/cpu_map/index.xml +@@ -66,6 +66,7 @@ + <include filename="x86_Opteron_G5.xml"/> + <include filename="x86_EPYC.xml"/> + <include filename="x86_EPYC-IBPB.xml"/> ++ <include filename="x86_EPYC-Rome.xml"/> + + <!-- Hygon CPU models --> + <include filename="x86_Dhyana.xml"/> +diff --git a/src/cpu_map/x86_EPYC-Rome.xml b/src/cpu_map/x86_EPYC-Rome.xml +new file mode 100644 +index 0000000000..99fc015fdd +--- /dev/null ++++ b/src/cpu_map/x86_EPYC-Rome.xml +@@ -0,0 +1,84 @@ ++<cpus> ++ <model name='EPYC-Rome'> ++ <decode host='on' guest='on'/> ++ <signature family='23' model='49'/> ++ <vendor name='AMD'/> ++ <feature name='3dnowprefetch'/> ++ <feature name='abm'/> ++ <feature name='adx'/> ++ <feature name='aes'/> ++ <feature name='amd-stibp'/> ++ <feature name='apic'/> ++ <feature name='arat'/> ++ <feature name='avx'/> ++ <feature name='avx2'/> ++ <feature name='bmi1'/> ++ <feature name='bmi2'/> ++ <feature name='clflush'/> ++ <feature name='clflushopt'/> ++ <feature name='clwb'/> ++ <feature name='clzero'/> ++ <feature name='cmov'/> ++ <feature name='cr8legacy'/> ++ <feature name='cx16'/> ++ <feature name='cx8'/> ++ <feature name='de'/> ++ <feature name='f16c'/> ++ <feature name='fma'/> ++ <feature name='fpu'/> ++ <feature name='fsgsbase'/> ++ <feature name='fxsr'/> ++ <feature name='fxsr_opt'/> ++ <feature name='ibpb'/> ++ <feature name='lahf_lm'/> ++ <feature name='lm'/> ++ <feature name='mca'/> ++ <feature name='mce'/> ++ <feature name='misalignsse'/> ++ <feature name='mmx'/> ++ <feature name='mmxext'/> ++ <feature name='monitor'/> ++ <feature name='movbe'/> ++ <feature name='msr'/> ++ <feature name='mtrr'/> ++ <feature name='npt'/> ++ <feature name='nrip-save'/> ++ <feature name='nx'/> ++ <feature name='osvw'/> ++ <feature name='pae'/> ++ <feature name='pat'/> ++ <feature name='pclmuldq'/> ++ <feature name='pdpe1gb'/> ++ <feature name='perfctr_core'/> ++ <feature name='pge'/> ++ <feature name='pni'/> ++ <feature name='popcnt'/> ++ <feature name='pse'/> ++ <feature name='pse36'/> ++ <feature name='rdpid'/> ++ <feature name='rdrand'/> ++ <feature name='rdseed'/> ++ <feature name='rdtscp'/> ++ <feature name='sep'/> ++ <feature name='sha-ni'/> ++ <feature name='smap'/> ++ <feature name='smep'/> ++ <feature name='sse'/> ++ <feature name='sse2'/> ++ <feature name='sse4.1'/> ++ <feature name='sse4.2'/> ++ <feature name='sse4a'/> ++ <feature name='ssse3'/> ++ <feature name='svm'/> ++ <feature name='syscall'/> ++ <feature name='tsc'/> ++ <feature name='umip'/> ++ <feature name='vme'/> ++ <feature name='wbnoinvd'/> ++ <feature name='xgetbv1'/> ++ <feature name='xsave'/> ++ <feature name='xsavec'/> ++ <feature name='xsaveerptr'/> ++ <feature name='xsaveopt'/> ++ </model> ++</cpus> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml +index 1320f65a58..cb2caab6f5 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml +@@ -1,12 +1,9 @@ + <cpu mode='custom' match='exact'> +- <model fallback='forbid'>EPYC-IBPB</model> ++ <model fallback='forbid'>EPYC-Rome</model> + <vendor>AMD</vendor> + <feature policy='require' name='ht'/> + <feature policy='require' name='osxsave'/> + <feature policy='require' name='cmt'/> +- <feature policy='require' name='clwb'/> +- <feature policy='require' name='umip'/> +- <feature policy='require' name='rdpid'/> + <feature policy='require' name='xsaves'/> + <feature policy='require' name='mbm_total'/> + <feature policy='require' name='mbm_local'/> +@@ -17,18 +14,11 @@ + <feature policy='require' name='wdt'/> + <feature policy='require' name='tce'/> + <feature policy='require' name='topoext'/> +- <feature policy='require' name='perfctr_core'/> + <feature policy='require' name='perfctr_nb'/> + <feature policy='require' name='invtsc'/> +- <feature policy='require' name='clzero'/> +- <feature policy='require' name='xsaveerptr'/> +- <feature policy='require' name='wbnoinvd'/> +- <feature policy='require' name='amd-stibp'/> + <feature policy='require' name='amd-ssbd'/> +- <feature policy='require' name='npt'/> + <feature policy='require' name='lbrv'/> + <feature policy='require' name='svm-lock'/> +- <feature policy='require' name='nrip-save'/> + <feature policy='require' name='tsc-scale'/> + <feature policy='require' name='vmcb-clean'/> + <feature policy='require' name='flushbyasid'/> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml +index 37905ec812..b6784f9eba 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml +@@ -1,13 +1,10 @@ + <cpu> + <arch>x86_64</arch> +- <model>EPYC-IBPB</model> ++ <model>EPYC-Rome</model> + <vendor>AMD</vendor> + <feature name='ht'/> + <feature name='osxsave'/> + <feature name='cmt'/> +- <feature name='clwb'/> +- <feature name='umip'/> +- <feature name='rdpid'/> + <feature name='xsaves'/> + <feature name='mbm_total'/> + <feature name='mbm_local'/> +@@ -18,18 +15,11 @@ + <feature name='wdt'/> + <feature name='tce'/> + <feature name='topoext'/> +- <feature name='perfctr_core'/> + <feature name='perfctr_nb'/> + <feature name='invtsc'/> +- <feature name='clzero'/> +- <feature name='xsaveerptr'/> +- <feature name='wbnoinvd'/> +- <feature name='amd-stibp'/> + <feature name='amd-ssbd'/> +- <feature name='npt'/> + <feature name='lbrv'/> + <feature name='svm-lock'/> +- <feature name='nrip-save'/> + <feature name='tsc-scale'/> + <feature name='vmcb-clean'/> + <feature name='flushbyasid'/> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml +index 225cf63852..86466c0547 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml +@@ -1,28 +1,18 @@ + <cpu mode='custom' match='exact'> +- <model fallback='forbid'>EPYC-IBPB</model> ++ <model fallback='forbid'>EPYC-Rome</model> + <vendor>AMD</vendor> + <feature policy='require' name='x2apic'/> + <feature policy='require' name='tsc-deadline'/> + <feature policy='require' name='hypervisor'/> + <feature policy='require' name='tsc_adjust'/> +- <feature policy='require' name='clwb'/> +- <feature policy='require' name='umip'/> +- <feature policy='require' name='rdpid'/> + <feature policy='require' name='spec-ctrl'/> + <feature policy='require' name='stibp'/> + <feature policy='require' name='arch-capabilities'/> + <feature policy='require' name='ssbd'/> + <feature policy='require' name='xsaves'/> + <feature policy='require' name='cmp_legacy'/> +- <feature policy='require' name='perfctr_core'/> +- <feature policy='require' name='clzero'/> +- <feature policy='require' name='xsaveerptr'/> +- <feature policy='require' name='wbnoinvd'/> +- <feature policy='require' name='amd-stibp'/> + <feature policy='require' name='amd-ssbd'/> + <feature policy='require' name='virt-ssbd'/> +- <feature policy='require' name='npt'/> +- <feature policy='require' name='nrip-save'/> + <feature policy='require' name='rdctl-no'/> + <feature policy='require' name='skip-l1dfl-vmentry'/> + <feature policy='require' name='mds-no'/> +diff --git a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml +index 7bfd786ff6..b2a7087a0e 100644 +--- a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml +@@ -90,6 +90,7 @@ + <model usable='yes'>Haswell-noTSX</model> + <model usable='yes'>Haswell-IBRS</model> + <model usable='yes'>Haswell</model> ++ <model usable='no'>EPYC-Rome</model> + <model usable='no'>EPYC-IBPB</model> + <model usable='no'>EPYC</model> + <model usable='no'>Dhyana</model> +diff --git a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml +index eb456dea28..39b11fb634 100644 +--- a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml +@@ -100,6 +100,7 @@ + <model usable='no'>Haswell-noTSX</model> + <model usable='no'>Haswell-IBRS</model> + <model usable='no'>Haswell</model> ++ <model usable='no'>EPYC-Rome</model> + <model usable='no'>EPYC-IBPB</model> + <model usable='no'>EPYC</model> + <model usable='no'>Dhyana</model> +diff --git a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml +index d6ee66ab60..3a1ee23302 100644 +--- a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml ++++ b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml +@@ -89,6 +89,7 @@ + <model usable='yes'>Haswell-noTSX</model> + <model usable='yes'>Haswell-IBRS</model> + <model usable='yes'>Haswell</model> ++ <model usable='no'>EPYC-Rome</model> + <model usable='no'>EPYC-IBPB</model> + <model usable='no'>EPYC</model> + <model usable='no'>Dhyana</model> +-- +2.29.2 + diff --git a/SOURCES/libvirt-cpu_map-Fix-Icelake-Server-model-number.patch b/SOURCES/libvirt-cpu_map-Fix-Icelake-Server-model-number.patch new file mode 100644 index 0000000..0ec9af6 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Fix-Icelake-Server-model-number.patch @@ -0,0 +1,52 @@ +From a6293a2b28a65f3c9ae0dcf387b222ebd242fa63 Mon Sep 17 00:00:00 2001 +Message-Id: <a6293a2b28a65f3c9ae0dcf387b222ebd242fa63@dist-git> +From: Tim Wiederhake <twiederh@redhat.com> +Date: Fri, 15 Jan 2021 15:17:17 +0100 +Subject: [PATCH] cpu_map: Fix Icelake Server model number + +See arch/x86/include/asm/intel-family.h in the Kernel: + #define INTEL_FAM6_ICELAKE_X 0x6A + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +(cherry picked from commit 1278ac6265589cd83cc2e661056c860e98105507) + +https://bugzilla.redhat.com/show_bug.cgi?id=1537734 + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Message-Id: <20210115141722.14986-2-twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/cpu_map/x86_Icelake-Server-noTSX.xml | 2 +- + src/cpu_map/x86_Icelake-Server.xml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/cpu_map/x86_Icelake-Server-noTSX.xml b/src/cpu_map/x86_Icelake-Server-noTSX.xml +index 2fd6906406..34a0f7c18c 100644 +--- a/src/cpu_map/x86_Icelake-Server-noTSX.xml ++++ b/src/cpu_map/x86_Icelake-Server-noTSX.xml +@@ -1,7 +1,7 @@ + <cpus> + <model name='Icelake-Server-noTSX'> + <decode host='on' guest='off'/> +- <signature family='6' model='134'/> <!-- 080660 --> ++ <signature family='6' model='106'/> <!-- 0606A5 --> + <vendor name='Intel'/> + <feature name='3dnowprefetch'/> + <feature name='abm'/> +diff --git a/src/cpu_map/x86_Icelake-Server.xml b/src/cpu_map/x86_Icelake-Server.xml +index 367ade7240..1ee4ea9cd4 100644 +--- a/src/cpu_map/x86_Icelake-Server.xml ++++ b/src/cpu_map/x86_Icelake-Server.xml +@@ -1,7 +1,7 @@ + <cpus> + <model name='Icelake-Server'> + <decode host='on' guest='on'/> +- <signature family='6' model='134'/> <!-- 080660 --> ++ <signature family='6' model='106'/> <!-- 0606A5 --> + <vendor name='Intel'/> + <feature name='3dnowprefetch'/> + <feature name='abm'/> +-- +2.30.0 + diff --git a/SOURCES/libvirt-cpu_map-Fix-spelling-of-svme-addr-chk-feature.patch b/SOURCES/libvirt-cpu_map-Fix-spelling-of-svme-addr-chk-feature.patch new file mode 100644 index 0000000..a603df9 --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Fix-spelling-of-svme-addr-chk-feature.patch @@ -0,0 +1,59 @@ +From a7fb45c4e5a807a7b437a91cfc96c8c811351578 Mon Sep 17 00:00:00 2001 +Message-Id: <a7fb45c4e5a807a7b437a91cfc96c8c811351578@dist-git> +From: Jiri Denemark <jdenemar@redhat.com> +Date: Thu, 4 Mar 2021 09:41:53 +0100 +Subject: [PATCH] cpu_map: Fix spelling of svme-addr-chk feature +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit a208176ca1d9eedf8aa6bf12fde6a7a9579ab549 introduced this feature +with an incorrect "svme-addr-check" spelling. + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Reviewed-by: Tim Wiederhake <twiederh@redhat.com> +(cherry picked from commit b5abf9a192248b1005f63a7102d2627375d70fe5) + +https://bugzilla.redhat.com/show_bug.cgi?id=1926864 + +Conflicts: + src/cpu_map/sync_qemu_i386.py + - the original change to this file was not backported + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Message-Id: <75071287f9fc55f4bec82916726fcb8f31c1e014.1614847231.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/cpu_map/x86_EPYC-Milan.xml | 2 +- + src/cpu_map/x86_features.xml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/cpu_map/x86_EPYC-Milan.xml b/src/cpu_map/x86_EPYC-Milan.xml +index 53f0cd6aac..3055e175fa 100644 +--- a/src/cpu_map/x86_EPYC-Milan.xml ++++ b/src/cpu_map/x86_EPYC-Milan.xml +@@ -76,7 +76,7 @@ + <feature name='sse4a'/> + <feature name='ssse3'/> + <feature name='svm'/> +- <feature name='svme-addr-check'/> ++ <feature name='svme-addr-chk'/> + <feature name='syscall'/> + <feature name='tsc'/> + <feature name='umip'/> +diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml +index 8acd42f796..ba23f553c3 100644 +--- a/src/cpu_map/x86_features.xml ++++ b/src/cpu_map/x86_features.xml +@@ -548,7 +548,7 @@ + <feature name='pfthreshold'> + <cpuid eax_in='0x8000000a' edx='0x00001000'/> + </feature> +- <feature name='svme-addr-check'> ++ <feature name='svme-addr-chk'> + <cpuid eax_in='0x8000000a' edx='0x10000000'/> + </feature> + +-- +2.30.0 + diff --git a/SOURCES/libvirt-cpu_map-Install-x86_EPYC-Milan.xml.patch b/SOURCES/libvirt-cpu_map-Install-x86_EPYC-Milan.xml.patch new file mode 100644 index 0000000..4652d0e --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Install-x86_EPYC-Milan.xml.patch @@ -0,0 +1,41 @@ +From 8b1e1aa7cb9dc428a36b549a73286ec7040864ed Mon Sep 17 00:00:00 2001 +Message-Id: <8b1e1aa7cb9dc428a36b549a73286ec7040864ed@dist-git> +From: Jiri Denemark <jdenemar@redhat.com> +Date: Wed, 3 Mar 2021 11:11:55 +0100 +Subject: [PATCH] cpu_map: Install x86_EPYC-Milan.xml +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Reviewed-by: Pavel Hrdina <phrdina@redhat.com> +(cherry picked from commit d3de79dbfc20dc4dfc19154b16079861c542b71e) + +https://bugzilla.redhat.com/show_bug.cgi?id=1926864 + +Conflicts: + src/cpu_map/meson.build + - change goes to Makefile.inc.am instead + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Message-Id: <77cf69a7222fd9fc5ef0f1c25f0534090c29865f.1614766279.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/cpu_map/Makefile.inc.am | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/cpu_map/Makefile.inc.am b/src/cpu_map/Makefile.inc.am +index 1dd78c6715..45dbe9e216 100644 +--- a/src/cpu_map/Makefile.inc.am ++++ b/src/cpu_map/Makefile.inc.am +@@ -30,6 +30,7 @@ cpumap_DATA = \ + cpu_map/x86_Dhyana.xml \ + cpu_map/x86_EPYC.xml \ + cpu_map/x86_EPYC-IBPB.xml \ ++ cpu_map/x86_EPYC-Milan.xml \ + cpu_map/x86_EPYC-Rome.xml \ + cpu_map/x86_Haswell.xml \ + cpu_map/x86_Haswell-IBRS.xml \ +-- +2.30.0 + diff --git a/SOURCES/libvirt-cpu_map-Remove-monitor-feature-from-EPYC-Rome.patch b/SOURCES/libvirt-cpu_map-Remove-monitor-feature-from-EPYC-Rome.patch new file mode 100644 index 0000000..09af67b --- /dev/null +++ b/SOURCES/libvirt-cpu_map-Remove-monitor-feature-from-EPYC-Rome.patch @@ -0,0 +1,90 @@ +From b91bb231645300a29ab82994a003ba22835ee994 Mon Sep 17 00:00:00 2001 +Message-Id: <b91bb231645300a29ab82994a003ba22835ee994@dist-git> +From: Jiri Denemark <jdenemar@redhat.com> +Date: Thu, 8 Oct 2020 18:01:26 +0200 +Subject: [PATCH] cpu_map: Remove monitor feature from EPYC-Rome +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The feature is filtered by KVM and never automatically enabled. So even +though QEMU definition of EPYC-Rome contains this feature, the guest +won't see it. Also domain capabilities will show it as disabled for KVM +domains. Thus the feature should not really be included in our +definition of EPYC-Rome. + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Reviewed-by: Peter Krempa <pkrempa@redhat.com> +(cherry picked from commit 3bf6f9fe22dfbd3c1dcc614b31f2f4fe8b71a2f2) + +https://bugzilla.redhat.com/show_bug.cgi?id=1861506 + +Conflicts: + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-guest.xml + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-host.xml + tests/cputestdata/x86_64-cpuid-Ryzen-9-3900X-12-Core-json.xml + tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml + tests/domaincapsdata/qemu_5.1.0.x86_64.xml + tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml + tests/domaincapsdata/qemu_5.2.0.x86_64.xml + - not present downstream + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Message-Id: <74b9257f49925312b025a99dd934a9613ca295d4.1602172344.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/cpu_map/x86_EPYC-Rome.xml | 1 - + tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml | 1 + + tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml | 1 + + tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml | 1 - + 4 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/cpu_map/x86_EPYC-Rome.xml b/src/cpu_map/x86_EPYC-Rome.xml +index 99fc015fdd..e54d0a48d8 100644 +--- a/src/cpu_map/x86_EPYC-Rome.xml ++++ b/src/cpu_map/x86_EPYC-Rome.xml +@@ -37,7 +37,6 @@ + <feature name='misalignsse'/> + <feature name='mmx'/> + <feature name='mmxext'/> +- <feature name='monitor'/> + <feature name='movbe'/> + <feature name='msr'/> + <feature name='mtrr'/> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml +index cb2caab6f5..6d95b508b2 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml +@@ -2,6 +2,7 @@ + <model fallback='forbid'>EPYC-Rome</model> + <vendor>AMD</vendor> + <feature policy='require' name='ht'/> ++ <feature policy='require' name='monitor'/> + <feature policy='require' name='osxsave'/> + <feature policy='require' name='cmt'/> + <feature policy='require' name='xsaves'/> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml +index b6784f9eba..65eaeabdd0 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml +@@ -3,6 +3,7 @@ + <model>EPYC-Rome</model> + <vendor>AMD</vendor> + <feature name='ht'/> ++ <feature name='monitor'/> + <feature name='osxsave'/> + <feature name='cmt'/> + <feature name='xsaves'/> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml +index 86466c0547..febfdfcf2b 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-json.xml +@@ -17,5 +17,4 @@ + <feature policy='require' name='skip-l1dfl-vmentry'/> + <feature policy='require' name='mds-no'/> + <feature policy='require' name='pschange-mc-no'/> +- <feature policy='disable' name='monitor'/> + </cpu> +-- +2.29.2 + diff --git a/SOURCES/libvirt-cpumap-Add-support-for-ibrs-CPU-feature.patch b/SOURCES/libvirt-cpumap-Add-support-for-ibrs-CPU-feature.patch new file mode 100644 index 0000000..9fcd3a4 --- /dev/null +++ b/SOURCES/libvirt-cpumap-Add-support-for-ibrs-CPU-feature.patch @@ -0,0 +1,65 @@ +From bb9f39342d4ea6b76b67378f514f52a9627206b9 Mon Sep 17 00:00:00 2001 +Message-Id: <bb9f39342d4ea6b76b67378f514f52a9627206b9@dist-git> +From: Tim Wiederhake <twiederh@redhat.com> +Date: Wed, 3 Mar 2021 11:11:52 +0100 +Subject: [PATCH] cpumap: Add support for ibrs CPU feature +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +(cherry picked from commit 5c17a7ba41670f3182186c06e621995b5d03fc95) + +https://bugzilla.redhat.com/show_bug.cgi?id=1926864 + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Message-Id: <0aee3baa35e04f56e3c95bb2f60c8a17d7806e7a.1614766279.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/cpu_map/x86_features.xml | 3 +++ + tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml | 1 + + tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml | 1 + + 3 files changed, 5 insertions(+) + +diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml +index 83d8e641a8..abefb7928e 100644 +--- a/src/cpu_map/x86_features.xml ++++ b/src/cpu_map/x86_features.xml +@@ -501,6 +501,9 @@ + <feature name='ibpb'> + <cpuid eax_in='0x80000008' ebx='0x00001000'/> + </feature> ++ <feature name='ibrs'> ++ <cpuid eax_in='0x80000008' ebx='0x00004000'/> ++ </feature> + <feature name='amd-stibp'> + <cpuid eax_in='0x80000008' ebx='0x00008000'/> + </feature> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml +index 6d95b508b2..40e7912398 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-guest.xml +@@ -17,6 +17,7 @@ + <feature policy='require' name='topoext'/> + <feature policy='require' name='perfctr_nb'/> + <feature policy='require' name='invtsc'/> ++ <feature policy='require' name='ibrs'/> + <feature policy='require' name='amd-ssbd'/> + <feature policy='require' name='lbrv'/> + <feature policy='require' name='svm-lock'/> +diff --git a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml +index 65eaeabdd0..9f8108cdaa 100644 +--- a/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml ++++ b/tests/cputestdata/x86_64-cpuid-EPYC-7502-32-Core-host.xml +@@ -18,6 +18,7 @@ + <feature name='topoext'/> + <feature name='perfctr_nb'/> + <feature name='invtsc'/> ++ <feature name='ibrs'/> + <feature name='amd-ssbd'/> + <feature name='lbrv'/> + <feature name='svm-lock'/> +-- +2.30.0 + diff --git a/SOURCES/libvirt-cpumap-Add-support-for-svme-addr-check-CPU-feature.patch b/SOURCES/libvirt-cpumap-Add-support-for-svme-addr-check-CPU-feature.patch new file mode 100644 index 0000000..97d1b6f --- /dev/null +++ b/SOURCES/libvirt-cpumap-Add-support-for-svme-addr-check-CPU-feature.patch @@ -0,0 +1,39 @@ +From 87fdbd2d0ab24f00c70a298317d50df44a5f76ad Mon Sep 17 00:00:00 2001 +Message-Id: <87fdbd2d0ab24f00c70a298317d50df44a5f76ad@dist-git> +From: Tim Wiederhake <twiederh@redhat.com> +Date: Wed, 3 Mar 2021 11:11:53 +0100 +Subject: [PATCH] cpumap: Add support for svme-addr-check CPU feature +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +(cherry picked from commit 5ac6ab2fde63881d3c5cc7372a0d0e59618feb55) + +https://bugzilla.redhat.com/show_bug.cgi?id=1926864 + +Signed-off-by: Jiri Denemark <jdenemar@redhat.com> +Message-Id: <aa154754f76021b9f61788944f6c329c6088cf77.1614766279.git.jdenemar@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/cpu_map/x86_features.xml | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/cpu_map/x86_features.xml b/src/cpu_map/x86_features.xml +index abefb7928e..8acd42f796 100644 +--- a/src/cpu_map/x86_features.xml ++++ b/src/cpu_map/x86_features.xml +@@ -548,6 +548,9 @@ + <feature name='pfthreshold'> + <cpuid eax_in='0x8000000a' edx='0x00001000'/> + </feature> ++ <feature name='svme-addr-check'> ++ <cpuid eax_in='0x8000000a' edx='0x10000000'/> ++ </feature> + + <!-- IA32_ARCH_CAPABILITIES features --> + <feature name='rdctl-no'> +-- +2.30.0 + diff --git a/SOURCES/libvirt-cputestdata-Add-test-data-for-Snowridge.patch b/SOURCES/libvirt-cputestdata-Add-test-data-for-Snowridge.patch new file mode 100644 index 0000000..0ee3ed2 --- /dev/null +++ b/SOURCES/libvirt-cputestdata-Add-test-data-for-Snowridge.patch @@ -0,0 +1,2763 @@ +From 2d95faf1042465489753179ca46b7ade6225b171 Mon Sep 17 00:00:00 2001 +Message-Id: <2d95faf1042465489753179ca46b7ade6225b171@dist-git> +From: Tim Wiederhake <twiederh@redhat.com> +Date: Fri, 15 Jan 2021 15:17:18 +0100 +Subject: [PATCH] cputestdata: Add test data for Snowridge + +It's obvious the CPU model detection provides strange results, which +will be fixed by adding a new Snowridge CPU model few patches later. + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +(cherry picked from commit 59a585fdb047669ee36251c7338bb2e2ccd58998) + +https://bugzilla.redhat.com/show_bug.cgi?id=1537734 + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Message-Id: <20210115141722.14986-3-twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + tests/cputest.c | 1 + + .../x86_64-cpuid-Atom-P5362-disabled.xml | 8 + + .../x86_64-cpuid-Atom-P5362-enabled.xml | 10 + + .../x86_64-cpuid-Atom-P5362-guest.xml | 57 + + .../x86_64-cpuid-Atom-P5362-host.xml | 66 + + .../x86_64-cpuid-Atom-P5362-json.xml | 41 + + .../cputestdata/x86_64-cpuid-Atom-P5362.json | 2415 +++++++++++++++++ + tests/cputestdata/x86_64-cpuid-Atom-P5362.sig | 4 + + tests/cputestdata/x86_64-cpuid-Atom-P5362.xml | 61 + + 9 files changed, 2663 insertions(+) + create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362-enabled.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml + create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362.json + create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362.sig + create mode 100644 tests/cputestdata/x86_64-cpuid-Atom-P5362.xml + +diff --git a/tests/cputest.c b/tests/cputest.c +index 388174eba7..2ec3337476 100644 +--- a/tests/cputest.c ++++ b/tests/cputest.c +@@ -1218,6 +1218,7 @@ mymain(void) + DO_TEST_CPUID(VIR_ARCH_X86_64, "A10-5800K", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Atom-D510", JSON_NONE); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Atom-N450", JSON_NONE); ++ DO_TEST_CPUID(VIR_ARCH_X86_64, "Atom-P5362", JSON_MODELS_REQUIRED); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i5-650", JSON_MODELS_REQUIRED); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i5-2500", JSON_HOST); + DO_TEST_CPUID(VIR_ARCH_X86_64, "Core-i5-2540M", JSON_MODELS); +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml +new file mode 100644 +index 0000000000..842c7b4a2a +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-disabled.xml +@@ -0,0 +1,8 @@ ++<!-- Features disabled by QEMU --> ++<cpudata arch='x86'> ++ <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x080041dc' edx='0xb0600000'/> ++ <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x02001000' ecx='0x00000020' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000006'/> ++ <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> ++ <msr index='0x10a' edx='0x00000000' eax='0x00000100'/> ++</cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-enabled.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-enabled.xml +new file mode 100644 +index 0000000000..2214d448ef +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-enabled.xml +@@ -0,0 +1,10 @@ ++<!-- Features enabled by QEMU --> ++<cpudata arch='x86'> ++ <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0xc7f8a223' edx='0x0f8bfbff'/> ++ <cpuid eax_in='0x00000006' ecx_in='0x00' eax='0x00000004' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x21940283' ecx='0x1a400104' edx='0xac000400'/> ++ <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x0000000f' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000101' edx='0x28100800'/> ++ <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x00000000' ebx='0x01009000' ecx='0x00000000' edx='0x00000000'/> ++ <msr index='0x10a' edx='0x00000000' eax='0x0000006b'/> ++</cpudata> +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml +new file mode 100644 +index 0000000000..0f3e2e506e +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-guest.xml +@@ -0,0 +1,57 @@ ++<cpu mode='custom' match='exact'> ++ <model fallback='forbid'>IvyBridge-IBRS</model> ++ <vendor>Intel</vendor> ++ <feature policy='require' name='ds'/> ++ <feature policy='require' name='acpi'/> ++ <feature policy='require' name='ss'/> ++ <feature policy='require' name='ht'/> ++ <feature policy='require' name='tm'/> ++ <feature policy='require' name='pbe'/> ++ <feature policy='require' name='dtes64'/> ++ <feature policy='require' name='monitor'/> ++ <feature policy='require' name='ds_cpl'/> ++ <feature policy='require' name='vmx'/> ++ <feature policy='require' name='smx'/> ++ <feature policy='require' name='est'/> ++ <feature policy='require' name='tm2'/> ++ <feature policy='require' name='xtpr'/> ++ <feature policy='require' name='pdcm'/> ++ <feature policy='require' name='movbe'/> ++ <feature policy='require' name='osxsave'/> ++ <feature policy='require' name='arat'/> ++ <feature policy='require' name='tsc_adjust'/> ++ <feature policy='require' name='cmt'/> ++ <feature policy='require' name='rdseed'/> ++ <feature policy='require' name='smap'/> ++ <feature policy='require' name='clflushopt'/> ++ <feature policy='require' name='clwb'/> ++ <feature policy='require' name='intel-pt'/> ++ <feature policy='require' name='sha-ni'/> ++ <feature policy='require' name='umip'/> ++ <feature policy='require' name='waitpkg'/> ++ <feature policy='require' name='gfni'/> ++ <feature policy='require' name='rdpid'/> ++ <feature policy='require' name='cldemote'/> ++ <feature policy='require' name='movdiri'/> ++ <feature policy='require' name='movdir64b'/> ++ <feature policy='require' name='md-clear'/> ++ <feature policy='require' name='stibp'/> ++ <feature policy='require' name='arch-capabilities'/> ++ <feature policy='require' name='ssbd'/> ++ <feature policy='require' name='xsaveopt'/> ++ <feature policy='require' name='xsavec'/> ++ <feature policy='require' name='xgetbv1'/> ++ <feature policy='require' name='xsaves'/> ++ <feature policy='require' name='mbm_total'/> ++ <feature policy='require' name='mbm_local'/> ++ <feature policy='require' name='3dnowprefetch'/> ++ <feature policy='require' name='invtsc'/> ++ <feature policy='require' name='rdctl-no'/> ++ <feature policy='require' name='ibrs-all'/> ++ <feature policy='require' name='skip-l1dfl-vmentry'/> ++ <feature policy='require' name='mds-no'/> ++ <feature policy='require' name='pschange-mc-no'/> ++ <feature policy='require' name='taa-no'/> ++ <feature policy='disable' name='avx'/> ++ <feature policy='disable' name='f16c'/> ++</cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml +new file mode 100644 +index 0000000000..3bd009c1da +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-host.xml +@@ -0,0 +1,66 @@ ++<cpu> ++ <arch>x86_64</arch> ++ <model>Westmere-IBRS</model> ++ <vendor>Intel</vendor> ++ <feature name='vme'/> ++ <feature name='ds'/> ++ <feature name='acpi'/> ++ <feature name='ss'/> ++ <feature name='ht'/> ++ <feature name='tm'/> ++ <feature name='pbe'/> ++ <feature name='pclmuldq'/> ++ <feature name='dtes64'/> ++ <feature name='monitor'/> ++ <feature name='ds_cpl'/> ++ <feature name='vmx'/> ++ <feature name='smx'/> ++ <feature name='est'/> ++ <feature name='tm2'/> ++ <feature name='xtpr'/> ++ <feature name='pdcm'/> ++ <feature name='x2apic'/> ++ <feature name='movbe'/> ++ <feature name='tsc-deadline'/> ++ <feature name='xsave'/> ++ <feature name='osxsave'/> ++ <feature name='rdrand'/> ++ <feature name='arat'/> ++ <feature name='fsgsbase'/> ++ <feature name='tsc_adjust'/> ++ <feature name='smep'/> ++ <feature name='erms'/> ++ <feature name='cmt'/> ++ <feature name='rdseed'/> ++ <feature name='smap'/> ++ <feature name='clflushopt'/> ++ <feature name='clwb'/> ++ <feature name='intel-pt'/> ++ <feature name='sha-ni'/> ++ <feature name='umip'/> ++ <feature name='waitpkg'/> ++ <feature name='gfni'/> ++ <feature name='rdpid'/> ++ <feature name='cldemote'/> ++ <feature name='movdiri'/> ++ <feature name='movdir64b'/> ++ <feature name='md-clear'/> ++ <feature name='stibp'/> ++ <feature name='arch-capabilities'/> ++ <feature name='ssbd'/> ++ <feature name='xsaveopt'/> ++ <feature name='xsavec'/> ++ <feature name='xgetbv1'/> ++ <feature name='xsaves'/> ++ <feature name='mbm_total'/> ++ <feature name='mbm_local'/> ++ <feature name='rdtscp'/> ++ <feature name='3dnowprefetch'/> ++ <feature name='invtsc'/> ++ <feature name='rdctl-no'/> ++ <feature name='ibrs-all'/> ++ <feature name='skip-l1dfl-vmentry'/> ++ <feature name='mds-no'/> ++ <feature name='pschange-mc-no'/> ++ <feature name='taa-no'/> ++</cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml +new file mode 100644 +index 0000000000..ca685d2f80 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362-json.xml +@@ -0,0 +1,41 @@ ++<cpu mode='custom' match='exact'> ++ <model fallback='forbid'>IvyBridge-IBRS</model> ++ <vendor>Intel</vendor> ++ <feature policy='require' name='ss'/> ++ <feature policy='require' name='vmx'/> ++ <feature policy='require' name='pdcm'/> ++ <feature policy='require' name='movbe'/> ++ <feature policy='require' name='hypervisor'/> ++ <feature policy='require' name='arat'/> ++ <feature policy='require' name='tsc_adjust'/> ++ <feature policy='require' name='rdseed'/> ++ <feature policy='require' name='smap'/> ++ <feature policy='require' name='clflushopt'/> ++ <feature policy='require' name='clwb'/> ++ <feature policy='require' name='sha-ni'/> ++ <feature policy='require' name='umip'/> ++ <feature policy='require' name='gfni'/> ++ <feature policy='require' name='rdpid'/> ++ <feature policy='require' name='cldemote'/> ++ <feature policy='require' name='movdiri'/> ++ <feature policy='require' name='movdir64b'/> ++ <feature policy='require' name='md-clear'/> ++ <feature policy='require' name='stibp'/> ++ <feature policy='require' name='arch-capabilities'/> ++ <feature policy='require' name='ssbd'/> ++ <feature policy='require' name='xsaveopt'/> ++ <feature policy='require' name='xsavec'/> ++ <feature policy='require' name='xgetbv1'/> ++ <feature policy='require' name='xsaves'/> ++ <feature policy='require' name='3dnowprefetch'/> ++ <feature policy='require' name='ibpb'/> ++ <feature policy='require' name='amd-stibp'/> ++ <feature policy='require' name='amd-ssbd'/> ++ <feature policy='require' name='rdctl-no'/> ++ <feature policy='require' name='ibrs-all'/> ++ <feature policy='require' name='skip-l1dfl-vmentry'/> ++ <feature policy='require' name='mds-no'/> ++ <feature policy='require' name='pschange-mc-no'/> ++ <feature policy='disable' name='avx'/> ++ <feature policy='disable' name='f16c'/> ++</cpu> +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362.json b/tests/cputestdata/x86_64-cpuid-Atom-P5362.json +new file mode 100644 +index 0000000000..4e5545f177 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362.json +@@ -0,0 +1,2415 @@ ++{ ++ "return": { ++ "model": { ++ "name": "base", ++ "props": { ++ "vmx-entry-load-rtit-ctl": false, ++ "phys-bits": 0, ++ "core-id": -1, ++ "xlevel": 2147483656, ++ "cmov": true, ++ "ia64": false, ++ "ssb-no": false, ++ "aes": true, ++ "vmx-apicv-xapic": true, ++ "mmx": true, ++ "rdpid": true, ++ "vmx-page-walk-4": true, ++ "vmx-page-walk-5": false, ++ "arat": true, ++ "gfni": true, ++ "vmx-desc-exit": true, ++ "ibrs-all": true, ++ "pause-filter": false, ++ "xsavec": true, ++ "intel-pt": false, ++ "vmx-cr8-store-exit": true, ++ "hv-frequencies": false, ++ "tsc-frequency": 0, ++ "vmx-rdseed-exit": true, ++ "xd": true, ++ "x-intel-pt-auto-level": false, ++ "hv-vendor-id": "", ++ "vmx-eptp-switching": true, ++ "kvm-asyncpf": true, ++ "kvm_asyncpf": true, ++ "perfctr_core": false, ++ "perfctr-core": false, ++ "mpx": false, ++ "pbe": false, ++ "decodeassists": false, ++ "avx512cd": false, ++ "vmx-exit-load-efer": true, ++ "vmx-exit-clear-bndcfgs": false, ++ "sse4_1": true, ++ "sse4.1": true, ++ "sse4-1": true, ++ "family": 6, ++ "legacy-cache": true, ++ "vmx-vmwrite-vmexit-fields": true, ++ "vmx-vnmi": true, ++ "vmx-true-ctls": true, ++ "host-phys-bits-limit": 48, ++ "vmx-ept-execonly": true, ++ "vmx-exit-save-efer": true, ++ "vmx-invept-all-context": true, ++ "vmware-cpuid-freq": true, ++ "wbnoinvd": false, ++ "avx512f": false, ++ "hv-stimer-direct": false, ++ "msr": true, ++ "mce": true, ++ "mca": true, ++ "hv-runtime": false, ++ "xcrypt": false, ++ "thread-id": -1, ++ "vmx-exit-load-pat": true, ++ "vmx-intr-exit": true, ++ "min-level": 27, ++ "vmx-flexpriority": true, ++ "xgetbv1": true, ++ "cid": false, ++ "hv-relaxed": false, ++ "hv-crash": false, ++ "ds": false, ++ "fxsr": true, ++ "avx512-bf16": false, ++ "vmx-cr8-load-exit": true, ++ "xsaveopt": true, ++ "vmx-apicv-vid": true, ++ "vmx-exit-save-pat": true, ++ "xtpr": false, ++ "tsx-ctrl": false, ++ "vmx-ple": false, ++ "hv-evmcs": false, ++ "avx512vl": false, ++ "avx512-vpopcntdq": false, ++ "phe": false, ++ "extapic": false, ++ "3dnowprefetch": true, ++ "vmx-vmfunc": true, ++ "vmx-activity-shutdown": false, ++ "avx512vbmi2": false, ++ "vmx-encls-exit": false, ++ "cr8legacy": false, ++ "vmx-msr-bitmap": true, ++ "stibp": true, ++ "cpuid-0xb": true, ++ "xcrypt-en": false, ++ "vmx-mwait-exit": true, ++ "kvm_pv_eoi": true, ++ "vmx-pml": true, ++ "apic-id": 4294967295, ++ "vmx-nmi-exit": true, ++ "vmx-invept-single-context-noglobals": true, ++ "rsba": false, ++ "pn": false, ++ "dca": false, ++ "vendor": "GenuineIntel", ++ "vmx-unrestricted-guest": true, ++ "hv-ipi": false, ++ "vmx-cr3-store-noexit": true, ++ "pku": false, ++ "smx": false, ++ "cmp_legacy": false, ++ "cmp-legacy": false, ++ "node-id": -1, ++ "avx512-4fmaps": false, ++ "vmcb_clean": false, ++ "vmcb-clean": false, ++ "3dnowext": false, ++ "amd-no-ssb": false, ++ "hle": false, ++ "npt": false, ++ "rdctl-no": true, ++ "vmx-invvpid": true, ++ "memory": "/machine/unattached/system[0]", ++ "clwb": true, ++ "lbrv": false, ++ "adx": false, ++ "ss": true, ++ "pni": true, ++ "svm_lock": false, ++ "svm-lock": false, ++ "pfthreshold": false, ++ "smep": true, ++ "smap": true, ++ "vmx-invpcid-exit": false, ++ "x2apic": true, ++ "avx512vbmi": false, ++ "avx512vnni": false, ++ "vmx-apicv-x2apic": true, ++ "kvm-pv-sched-yield": true, ++ "hv-stimer": false, ++ "vmx-invlpg-exit": true, ++ "x-hv-synic-kvm-only": true, ++ "vmx-invvpid-all-context": true, ++ "i64": true, ++ "vmx-activity-hlt": true, ++ "flushbyasid": false, ++ "f16c": false, ++ "vmx-exit-ack-intr": true, ++ "ace2-en": false, ++ "pat": true, ++ "pae": true, ++ "sse": true, ++ "die-id": -1, ++ "vmx-tsc-offset": true, ++ "phe-en": false, ++ "kvm_nopiodelay": true, ++ "kvm-nopiodelay": true, ++ "tm": false, ++ "kvmclock-stable-bit": true, ++ "vmx-rdtsc-exit": true, ++ "hypervisor": true, ++ "vmx-rdtscp-exit": true, ++ "socket-id": -1, ++ "mds-no": true, ++ "pcommit": false, ++ "vmx-vpid": true, ++ "syscall": true, ++ "level": 27, ++ "avx512dq": false, ++ "x-migrate-smi-count": false, ++ "svm": false, ++ "full-cpuid-auto-level": true, ++ "hv-reset": false, ++ "invtsc": false, ++ "vmx-monitor-exit": true, ++ "sse3": true, ++ "sse2": true, ++ "vmx-wbinvd-exit": true, ++ "ssbd": true, ++ "est": false, ++ "kvm-poll-control": true, ++ "kvm_poll_control": true, ++ "avx512ifma": false, ++ "tm2": false, ++ "kvm-pv-ipi": true, ++ "kvm-pv-eoi": true, ++ "cx8": true, ++ "vmx-invvpid-single-addr": true, ++ "waitpkg": false, ++ "cldemote": true, ++ "vmx-ept": true, ++ "hv-reenlightenment": false, ++ "kvm_mmu": false, ++ "kvm-mmu": false, ++ "sse4_2": true, ++ "sse4.2": true, ++ "sse4-2": true, ++ "pge": true, ++ "fill-mtrr-mask": true, ++ "avx512bitalg": false, ++ "nodeid_msr": false, ++ "vmx-entry-load-bndcfgs": false, ++ "pdcm": true, ++ "vmx-exit-clear-rtit-ctl": false, ++ "movbe": true, ++ "model": 134, ++ "nrip_save": false, ++ "nrip-save": false, ++ "kvm_pv_unhalt": true, ++ "ssse3": true, ++ "sse4a": false, ++ "vmx-pause-exit": true, ++ "invpcid": false, ++ "pdpe1gb": false, ++ "tsc-deadline": true, ++ "skip-l1dfl-vmentry": true, ++ "vmx-exit-load-perf-global-ctrl": false, ++ "fma": false, ++ "cx16": true, ++ "de": true, ++ "enforce": false, ++ "stepping": 5, ++ "xsave": true, ++ "clflush": true, ++ "skinit": false, ++ "tsc": true, ++ "tce": false, ++ "fpu": true, ++ "ibs": false, ++ "ds_cpl": false, ++ "ds-cpl": false, ++ "vmx-exit-nosave-debugctl": true, ++ "host-phys-bits": true, ++ "fma4": false, ++ "vmx-invept": true, ++ "la57": false, ++ "osvw": false, ++ "check": true, ++ "hv-spinlocks": 4294967295, ++ "vmx-eptad": true, ++ "pmu": false, ++ "pmm": false, ++ "apic": true, ++ "vmx-entry-noload-debugctl": true, ++ "spec-ctrl": true, ++ "vmx-posted-intr": true, ++ "vmx-apicv-register": true, ++ "min-xlevel2": 0, ++ "tsc-adjust": true, ++ "tsc_adjust": true, ++ "kvm-steal-time": true, ++ "kvm_steal_time": true, ++ "vmx-zero-len-inject": false, ++ "kvmclock": true, ++ "pschange-mc-no": true, ++ "l3-cache": true, ++ "vmx-rdrand-exit": true, ++ "lwp": false, ++ "hv-passthrough": false, ++ "amd-ssbd": true, ++ "ibpb": true, ++ "xop": false, ++ "avx": false, ++ "core-capability": false, ++ "vmx-invept-single-context": true, ++ "movdiri": true, ++ "ace2": false, ++ "avx512bw": false, ++ "acpi": false, ++ "hv-vapic": false, ++ "fsgsbase": true, ++ "vmx-ept-1gb": true, ++ "vmx-ept-2mb": true, ++ "ht": false, ++ "vmx-io-exit": true, ++ "nx": true, ++ "pclmulqdq": true, ++ "mmxext": false, ++ "vaes": false, ++ "popcnt": true, ++ "xsaves": true, ++ "movdir64b": true, ++ "tcg-cpuid": true, ++ "vmx-shadow-vmcs": true, ++ "lm": true, ++ "vmx-exit-save-preemption-timer": true, ++ "vmx-entry-load-pat": true, ++ "vmx-entry-load-perf-global-ctrl": false, ++ "vmx-io-bitmap": true, ++ "umip": true, ++ "vmx-store-lma": true, ++ "vmx-movdr-exit": true, ++ "pse": true, ++ "avx2": false, ++ "sep": true, ++ "pclmuldq": true, ++ "virt-ssbd": false, ++ "vmx-cr3-load-noexit": true, ++ "x-hv-max-vps": -1, ++ "nodeid-msr": false, ++ "md-clear": true, ++ "split-lock-detect": false, ++ "kvm": true, ++ "misalignsse": false, ++ "min-xlevel": 2147483656, ++ "kvm-pv-unhalt": true, ++ "bmi2": false, ++ "bmi1": false, ++ "realized": false, ++ "tsc_scale": false, ++ "tsc-scale": false, ++ "topoext": false, ++ "hv-vpindex": false, ++ "hv-no-nonarch-coresharing": "off", ++ "amd-stibp": true, ++ "vmx-preemption-timer": true, ++ "ucode-rev": 0, ++ "xlevel2": 0, ++ "clflushopt": true, ++ "vmx-vnmi-pending": true, ++ "kvm-no-smi-migration": false, ++ "monitor": false, ++ "vmx-vintr-pending": true, ++ "avx512er": false, ++ "pmm-en": false, ++ "pcid": false, ++ "taa-no": false, ++ "vmx-secondary-ctls": true, ++ "arch-capabilities": true, ++ "vmx-xsaves": true, ++ "clzero": false, ++ "3dnow": false, ++ "erms": true, ++ "vmx-entry-ia32e-mode": true, ++ "x-force-features": false, ++ "lahf_lm": true, ++ "lahf-lm": true, ++ "vpclmulqdq": false, ++ "vmx-ins-outs": true, ++ "fxsr-opt": false, ++ "hv-synic": false, ++ "xstore": false, ++ "fxsr_opt": false, ++ "kvm-hint-dedicated": false, ++ "rtm": false, ++ "lmce": true, ++ "hv-time": false, ++ "perfctr-nb": false, ++ "perfctr_nb": false, ++ "ffxsr": false, ++ "hv-tlbflush": false, ++ "rdrand": true, ++ "rdseed": true, ++ "avx512-4vnniw": false, ++ "vmx": true, ++ "vme": true, ++ "dtes64": false, ++ "mtrr": true, ++ "rdtscp": true, ++ "xsaveerptr": false, ++ "pse36": true, ++ "kvm-pv-tlb-flush": true, ++ "vmx-activity-wait-sipi": false, ++ "tbm": false, ++ "wdt": false, ++ "vmx-rdpmc-exit": true, ++ "level-func7": 0, ++ "vmx-entry-load-efer": true, ++ "vmx-mtf": true, ++ "pause_filter": false, ++ "sha-ni": true, ++ "model-id": "Intel Atom(R) P5362 processor", ++ "abm": false, ++ "vmx-ept-advanced-exitinfo": false, ++ "avx512pf": false, ++ "vmx-hlt-exit": true, ++ "xstore-en": false ++ } ++ } ++ }, ++ "id": "model-expansion" ++} ++ ++{ ++ "return": [ ++ { ++ "name": "max", ++ "typename": "max-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "host", ++ "typename": "host-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": false ++ }, ++ { ++ "name": "base", ++ "typename": "base-x86_64-cpu", ++ "unavailable-features": [], ++ "static": true, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu64-v1", ++ "typename": "qemu64-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu64", ++ "typename": "qemu64-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu32-v1", ++ "typename": "qemu32-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "qemu32", ++ "typename": "qemu32-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "phenom-v1", ++ "typename": "phenom-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "fxsr-opt", ++ "pdpe1gb", ++ "3dnowext", ++ "3dnow", ++ "abm", ++ "sse4a" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "phenom", ++ "typename": "phenom-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "fxsr-opt", ++ "pdpe1gb", ++ "3dnowext", ++ "3dnow", ++ "abm", ++ "sse4a" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium3-v1", ++ "typename": "pentium3-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium3", ++ "typename": "pentium3-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium2-v1", ++ "typename": "pentium2-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium2", ++ "typename": "pentium2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium-v1", ++ "typename": "pentium-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "pentium", ++ "typename": "pentium-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "n270-v1", ++ "typename": "n270-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "n270", ++ "typename": "n270-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm64-v1", ++ "typename": "kvm64-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm64", ++ "typename": "kvm64-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm32-v1", ++ "typename": "kvm32-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "kvm32", ++ "typename": "kvm32-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "coreduo-v1", ++ "typename": "coreduo-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "coreduo", ++ "typename": "coreduo-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "core2duo-v1", ++ "typename": "core2duo-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "core2duo", ++ "typename": "core2duo-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "athlon-v1", ++ "typename": "athlon-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "3dnowext", ++ "3dnow" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "athlon", ++ "typename": "athlon-x86_64-cpu", ++ "unavailable-features": [ ++ "mmxext", ++ "3dnowext", ++ "3dnow" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere-v2", ++ "typename": "Westmere-v2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere-v1", ++ "typename": "Westmere-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere-IBRS", ++ "typename": "Westmere-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Westmere", ++ "typename": "Westmere-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Snowridge-v2", ++ "typename": "Snowridge-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "core-capability", ++ "pdpe1gb", ++ "split-lock-detect" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Snowridge-v1", ++ "typename": "Snowridge-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "mpx", ++ "core-capability", ++ "pdpe1gb", ++ "mpx", ++ "mpx", ++ "split-lock-detect" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Snowridge", ++ "typename": "Snowridge-x86_64-cpu", ++ "unavailable-features": [ ++ "mpx", ++ "core-capability", ++ "pdpe1gb", ++ "mpx", ++ "mpx", ++ "split-lock-detect" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-v3", ++ "typename": "Skylake-Server-v3-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-v2", ++ "typename": "Skylake-Server-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-v1", ++ "typename": "Skylake-Server-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-noTSX-IBRS", ++ "typename": "Skylake-Server-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server-IBRS", ++ "typename": "Skylake-Server-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "mpx", ++ "mpx", ++ "avx512f", ++ "avx512f", ++ "avx512f" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Server", ++ "typename": "Skylake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "mpx", ++ "mpx", ++ "avx512f", ++ "avx512f", ++ "avx512f" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-v3", ++ "typename": "Skylake-Client-v3-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "adx", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-v2", ++ "typename": "Skylake-Client-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "adx", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-v1", ++ "typename": "Skylake-Client-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "adx", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-noTSX-IBRS", ++ "typename": "Skylake-Client-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "adx", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client-IBRS", ++ "typename": "Skylake-Client-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "adx", ++ "abm", ++ "avx", ++ "mpx", ++ "mpx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Skylake-Client", ++ "typename": "Skylake-Client-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "adx", ++ "abm", ++ "avx", ++ "mpx", ++ "mpx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge-v2", ++ "typename": "SandyBridge-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "avx", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge-v1", ++ "typename": "SandyBridge-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "avx", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge-IBRS", ++ "typename": "SandyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "avx", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "SandyBridge", ++ "typename": "SandyBridge-x86_64-cpu", ++ "unavailable-features": [ ++ "avx", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Penryn-v1", ++ "typename": "Penryn-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Penryn", ++ "typename": "Penryn-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G5-v1", ++ "typename": "Opteron_G5-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "pdpe1gb", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "xop", ++ "fma4", ++ "tbm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G5", ++ "typename": "Opteron_G5-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "pdpe1gb", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "xop", ++ "fma4", ++ "tbm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G4-v1", ++ "typename": "Opteron_G4-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "avx", ++ "pdpe1gb", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "xop", ++ "fma4", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G4", ++ "typename": "Opteron_G4-x86_64-cpu", ++ "unavailable-features": [ ++ "avx", ++ "pdpe1gb", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "xop", ++ "fma4", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G3-v1", ++ "typename": "Opteron_G3-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "abm", ++ "sse4a", ++ "misalignsse" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G3", ++ "typename": "Opteron_G3-x86_64-cpu", ++ "unavailable-features": [ ++ "abm", ++ "sse4a", ++ "misalignsse" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G2-v1", ++ "typename": "Opteron_G2-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G2", ++ "typename": "Opteron_G2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G1-v1", ++ "typename": "Opteron_G1-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Opteron_G1", ++ "typename": "Opteron_G1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem-v2", ++ "typename": "Nehalem-v2-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem-v1", ++ "typename": "Nehalem-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem-IBRS", ++ "typename": "Nehalem-IBRS-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Nehalem", ++ "typename": "Nehalem-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "KnightsMill-v1", ++ "typename": "KnightsMill-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "avx512f", ++ "adx", ++ "avx512pf", ++ "avx512er", ++ "avx512cd", ++ "avx512-vpopcntdq", ++ "avx512-4vnniw", ++ "avx512-4fmaps", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "KnightsMill", ++ "typename": "KnightsMill-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "avx512f", ++ "adx", ++ "avx512pf", ++ "avx512er", ++ "avx512cd", ++ "avx512-vpopcntdq", ++ "avx512-4vnniw", ++ "avx512-4fmaps", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge-v2", ++ "typename": "IvyBridge-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "avx", ++ "f16c", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge-v1", ++ "typename": "IvyBridge-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "avx", ++ "f16c", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge-IBRS", ++ "typename": "IvyBridge-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "avx", ++ "f16c", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "IvyBridge", ++ "typename": "IvyBridge-x86_64-cpu", ++ "unavailable-features": [ ++ "avx", ++ "f16c", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Server-v3", ++ "typename": "Icelake-Server-v3-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "la57", ++ "pdpe1gb", ++ "abm", ++ "wbnoinvd", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku", ++ "taa-no" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Server-v2", ++ "typename": "Icelake-Server-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "la57", ++ "pdpe1gb", ++ "abm", ++ "wbnoinvd", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Server-v1", ++ "typename": "Icelake-Server-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "la57", ++ "pdpe1gb", ++ "abm", ++ "wbnoinvd", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Server-noTSX", ++ "typename": "Icelake-Server-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "la57", ++ "pdpe1gb", ++ "abm", ++ "wbnoinvd", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Server", ++ "typename": "Icelake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "la57", ++ "pdpe1gb", ++ "abm", ++ "wbnoinvd", ++ "avx", ++ "mpx", ++ "mpx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Client-v2", ++ "typename": "Icelake-Client-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "adx", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "abm", ++ "wbnoinvd", ++ "avx", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Client-v1", ++ "typename": "Icelake-Client-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "adx", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "abm", ++ "wbnoinvd", ++ "avx", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Client-noTSX", ++ "typename": "Icelake-Client-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "adx", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "abm", ++ "wbnoinvd", ++ "avx", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Icelake-Client", ++ "typename": "Icelake-Client-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "adx", ++ "avx512vbmi", ++ "pku", ++ "avx512vbmi2", ++ "vaes", ++ "vpclmulqdq", ++ "avx512vnni", ++ "avx512bitalg", ++ "avx512-vpopcntdq", ++ "abm", ++ "wbnoinvd", ++ "avx", ++ "mpx", ++ "mpx", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-v4", ++ "typename": "Haswell-v4-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-v3", ++ "typename": "Haswell-v3-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-v2", ++ "typename": "Haswell-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-v1", ++ "typename": "Haswell-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX-IBRS", ++ "typename": "Haswell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-noTSX", ++ "typename": "Haswell-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell-IBRS", ++ "typename": "Haswell-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Haswell", ++ "typename": "Haswell-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-v2", ++ "typename": "EPYC-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "adx", ++ "mmxext", ++ "fxsr-opt", ++ "pdpe1gb", ++ "cr8legacy", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "osvw", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-v1", ++ "typename": "EPYC-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "adx", ++ "mmxext", ++ "fxsr-opt", ++ "pdpe1gb", ++ "cr8legacy", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "osvw", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-Rome-v1", ++ "typename": "EPYC-Rome-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "adx", ++ "mmxext", ++ "fxsr-opt", ++ "pdpe1gb", ++ "cr8legacy", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "osvw", ++ "perfctr-core", ++ "clzero", ++ "xsaveerptr", ++ "wbnoinvd", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-Rome", ++ "typename": "EPYC-Rome-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "adx", ++ "mmxext", ++ "fxsr-opt", ++ "pdpe1gb", ++ "cr8legacy", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "osvw", ++ "perfctr-core", ++ "clzero", ++ "xsaveerptr", ++ "wbnoinvd", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC-IBPB", ++ "typename": "EPYC-IBPB-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "adx", ++ "mmxext", ++ "fxsr-opt", ++ "pdpe1gb", ++ "cr8legacy", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "osvw", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "EPYC", ++ "typename": "EPYC-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "adx", ++ "mmxext", ++ "fxsr-opt", ++ "pdpe1gb", ++ "cr8legacy", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "osvw", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Dhyana-v1", ++ "typename": "Dhyana-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "adx", ++ "mmxext", ++ "fxsr-opt", ++ "pdpe1gb", ++ "cr8legacy", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "osvw", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Dhyana", ++ "typename": "Dhyana-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "adx", ++ "mmxext", ++ "fxsr-opt", ++ "pdpe1gb", ++ "cr8legacy", ++ "abm", ++ "sse4a", ++ "misalignsse", ++ "osvw", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Denverton-v1", ++ "typename": "Denverton-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "mpx", ++ "pdpe1gb", ++ "mpx", ++ "mpx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Denverton", ++ "typename": "Denverton-x86_64-cpu", ++ "unavailable-features": [ ++ "mpx", ++ "pdpe1gb", ++ "mpx", ++ "mpx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cooperlake-v1", ++ "typename": "Cooperlake-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "avx512-bf16", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku", ++ "taa-no" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cooperlake", ++ "typename": "Cooperlake-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "avx512-bf16", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku", ++ "taa-no" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Conroe-v1", ++ "typename": "Conroe-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Conroe", ++ "typename": "Conroe-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cascadelake-Server-v3", ++ "typename": "Cascadelake-Server-v3-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cascadelake-Server-v2", ++ "typename": "Cascadelake-Server-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cascadelake-Server-v1", ++ "typename": "Cascadelake-Server-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cascadelake-Server-noTSX", ++ "typename": "Cascadelake-Server-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Cascadelake-Server", ++ "typename": "Cascadelake-Server-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "mpx", ++ "avx512f", ++ "avx512dq", ++ "adx", ++ "avx512cd", ++ "avx512bw", ++ "avx512vl", ++ "pku", ++ "avx512vnni", ++ "pdpe1gb", ++ "abm", ++ "avx", ++ "mpx", ++ "mpx", ++ "avx512f", ++ "avx512f", ++ "avx512f", ++ "pku" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-v4", ++ "typename": "Broadwell-v4-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "adx", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-v3", ++ "typename": "Broadwell-v3-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "adx", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-v2", ++ "typename": "Broadwell-v2-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "adx", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-v1", ++ "typename": "Broadwell-v1-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "adx", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX-IBRS", ++ "typename": "Broadwell-noTSX-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "adx", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-noTSX", ++ "typename": "Broadwell-noTSX-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "adx", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell-IBRS", ++ "typename": "Broadwell-IBRS-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "adx", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "Broadwell", ++ "typename": "Broadwell-x86_64-cpu", ++ "unavailable-features": [ ++ "fma", ++ "pcid", ++ "avx", ++ "f16c", ++ "bmi1", ++ "hle", ++ "avx2", ++ "bmi2", ++ "invpcid", ++ "rtm", ++ "adx", ++ "abm", ++ "avx" ++ ], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "486-v1", ++ "typename": "486-v1-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ }, ++ { ++ "name": "486", ++ "typename": "486-x86_64-cpu", ++ "unavailable-features": [], ++ "static": false, ++ "migration-safe": true ++ } ++ ], ++ "id": "definitions" ++} +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362.sig b/tests/cputestdata/x86_64-cpuid-Atom-P5362.sig +new file mode 100644 +index 0000000000..788ae6efba +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362.sig +@@ -0,0 +1,4 @@ ++080665 ++family: 6 (0x06) ++model: 134 (0x86) ++stepping: 5 (0x05) +diff --git a/tests/cputestdata/x86_64-cpuid-Atom-P5362.xml b/tests/cputestdata/x86_64-cpuid-Atom-P5362.xml +new file mode 100644 +index 0000000000..4fe97c0866 +--- /dev/null ++++ b/tests/cputestdata/x86_64-cpuid-Atom-P5362.xml +@@ -0,0 +1,61 @@ ++<!-- Intel Atom(R) P5362 processor --> ++<cpudata arch='x86'> ++ <cpuid eax_in='0x00000000' ecx_in='0x00' eax='0x0000001b' ebx='0x756e6547' ecx='0x6c65746e' edx='0x49656e69'/> ++ <cpuid eax_in='0x00000001' ecx_in='0x00' eax='0x00080665' ebx='0x02800800' ecx='0x4ff8ebff' edx='0xbfebfbff'/> ++ <cpuid eax_in='0x00000002' ecx_in='0x00' eax='0x00feff01' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000003' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000004' ecx_in='0x00' eax='0xfc000121' ebx='0x01c0003f' ecx='0x0000003f' edx='0x00000000'/> ++ <cpuid eax_in='0x00000004' ecx_in='0x01' eax='0xfc000122' ebx='0x01c0003f' ecx='0x0000003f' edx='0x00000000'/> ++ <cpuid eax_in='0x00000004' ecx_in='0x02' eax='0xfc01c143' ebx='0x0440003f' ecx='0x00000fff' edx='0x00000000'/> ++ <cpuid eax_in='0x00000004' ecx_in='0x03' eax='0xfc1fc163' ebx='0x04c0003f' ecx='0x00002fff' edx='0x00000004'/> ++ <cpuid eax_in='0x00000005' ecx_in='0x00' eax='0x00000040' ebx='0x00000040' ecx='0x00000003' edx='0x00001020'/> ++ <cpuid eax_in='0x00000006' ecx_in='0x00' eax='0x00000075' ebx='0x00000002' ecx='0x00000009' edx='0x00000000'/> ++ <cpuid eax_in='0x00000007' ecx_in='0x00' eax='0x00000000' ebx='0x2394b2c3' ecx='0x1a400124' edx='0xfc000400'/> ++ <cpuid eax_in='0x00000008' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000009' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000a' ecx_in='0x00' eax='0x07300405' ebx='0x00000000' ecx='0x00000007' edx='0x00008603'/> ++ <cpuid eax_in='0x0000000b' ecx_in='0x00' eax='0x00000001' ebx='0x00000001' ecx='0x00000100' edx='0x00000002'/> ++ <cpuid eax_in='0x0000000b' ecx_in='0x01' eax='0x00000007' ebx='0x00000018' ecx='0x00000201' edx='0x00000002'/> ++ <cpuid eax_in='0x0000000c' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000d' ecx_in='0x00' eax='0x00000003' ebx='0x00000240' ecx='0x00000240' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000d' ecx_in='0x01' eax='0x0000000f' ebx='0x00000240' ecx='0x00000100' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000d' ecx_in='0x08' eax='0x00000080' ebx='0x00000000' ecx='0x00000001' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000e' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x0000000f' ecx_in='0x00' eax='0x00000000' ebx='0x0000002f' ecx='0x00000000' edx='0x00000002'/> ++ <cpuid eax_in='0x0000000f' ecx_in='0x01' eax='0x00000008' ebx='0x00003000' ecx='0x0000002f' edx='0x00000007'/> ++ <cpuid eax_in='0x00000010' ecx_in='0x00' eax='0x00000000' ebx='0x0000000e' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000010' ecx_in='0x01' eax='0x00000013' ebx='0x000c0000' ecx='0x00000004' edx='0x0000000d'/> ++ <cpuid eax_in='0x00000010' ecx_in='0x02' eax='0x00000011' ebx='0x00000000' ecx='0x00000004' edx='0x0000000d'/> ++ <cpuid eax_in='0x00000010' ecx_in='0x03' eax='0x00000059' ebx='0x00000000' ecx='0x00000004' edx='0x0000000d'/> ++ <cpuid eax_in='0x00000011' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000012' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000013' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000014' ecx_in='0x00' eax='0x00000001' ebx='0x0000007f' ecx='0x80000007' edx='0x00000000'/> ++ <cpuid eax_in='0x00000014' ecx_in='0x01' eax='0x02490002' ebx='0x003fffff' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000015' ecx_in='0x00' eax='0x00000002' ebx='0x000000b0' ecx='0x017d7840' edx='0x00000000'/> ++ <cpuid eax_in='0x00000016' ecx_in='0x00' eax='0x00000898' ebx='0x00000898' ecx='0x00000064' edx='0x00000000'/> ++ <cpuid eax_in='0x00000017' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000018' ecx_in='0x00' eax='0x00000005' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000018' ecx_in='0x01' eax='0x00000000' ebx='0x00300001' ecx='0x00000001' edx='0x00000121'/> ++ <cpuid eax_in='0x00000018' ecx_in='0x02' eax='0x00000000' ebx='0x00040001' ecx='0x00000100' edx='0x00000043'/> ++ <cpuid eax_in='0x00000018' ecx_in='0x03' eax='0x00000000' ebx='0x00040006' ecx='0x00000010' edx='0x00000043'/> ++ <cpuid eax_in='0x00000018' ecx_in='0x04' eax='0x00000000' ebx='0x00300001' ecx='0x00000001' edx='0x00000122'/> ++ <cpuid eax_in='0x00000018' ecx_in='0x05' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x00000019' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x0000001a' ecx_in='0x00' eax='0x20000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x0000001b' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x20000000' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000000' ecx_in='0x00' eax='0x80000008' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000001' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000101' edx='0x28100800'/> ++ <cpuid eax_in='0x80000002' ecx_in='0x00' eax='0x65746e49' ebx='0x7441206c' ecx='0x52286d6f' edx='0x35502029'/> ++ <cpuid eax_in='0x80000003' ecx_in='0x00' eax='0x20323633' ebx='0x636f7270' ecx='0x6f737365' edx='0x00000072'/> ++ <cpuid eax_in='0x80000004' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000005' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80000006' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x12008040' edx='0x00000000'/> ++ <cpuid eax_in='0x80000007' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000100'/> ++ <cpuid eax_in='0x80000008' ecx_in='0x00' eax='0x0000302a' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0x80860000' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <cpuid eax_in='0xc0000000' ecx_in='0x00' eax='0x00000000' ebx='0x00000000' ecx='0x00000000' edx='0x00000000'/> ++ <msr index='0xcf' edx='0x00000000' eax='0x00000060'/> ++ <msr index='0x10a' edx='0x001a8c7f' eax='0xa080036b'/> ++</cpudata> +-- +2.30.0 + diff --git a/SOURCES/libvirt-docs-use-proper-cpu-quota-value-in-our-documentation.patch b/SOURCES/libvirt-docs-use-proper-cpu-quota-value-in-our-documentation.patch new file mode 100644 index 0000000..abe880f --- /dev/null +++ b/SOURCES/libvirt-docs-use-proper-cpu-quota-value-in-our-documentation.patch @@ -0,0 +1,101 @@ +From c9113d8cd9d68c932175ea63b634fc5cb7e51ef2 Mon Sep 17 00:00:00 2001 +Message-Id: <c9113d8cd9d68c932175ea63b634fc5cb7e51ef2@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Thu, 4 Mar 2021 12:57:56 +0100 +Subject: [PATCH] docs: use proper cpu quota value in our documentation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit <d505b8af58912ae1e1a211fabc9995b19bd40828> changed the cpu quota +value that reflects what kernel allows but did not update our +documentation. + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit 992635b142b261cedb6075e459918418fe6e6962) + +Conflicts: + docs/formatdomain.rst + - missing in downstream, we use formatdomain.html.in + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <ba20be50c3bde1668cb214253e5ef8f212fc062b.1614858616.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + docs/formatdomain.html.in | 8 ++++---- + docs/manpages/virsh.rst | 2 +- + docs/schemas/domaincommon.rng | 2 +- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index 127dd13cc0..4341e256a8 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -872,7 +872,7 @@ + bandwidth (unit: microseconds). A domain with <code>quota</code> as any + negative value indicates that the domain has infinite bandwidth for + vCPU threads, which means that it is not bandwidth controlled. The value +- should be in range [1000, 18446744073709551] or less than 0. A quota ++ should be in range [1000, 17592186044415] or less than 0. A quota + with value 0 means no value. You can use this feature to ensure that all + vCPUs run at the same speed. + <span class="since">Only QEMU driver support since 0.9.4, LXC since +@@ -894,7 +894,7 @@ + domain. A domain with <code>global_quota</code> as any negative + value indicates that the domain has infinite bandwidth, which means that + it is not bandwidth controlled. The value should be in range +- [1000, 18446744073709551] or less than 0. A <code>global_quota</code> ++ [1000, 17592186044415] or less than 0. A <code>global_quota</code> + with value 0 means no value. + <span class="since">Only QEMU driver support since 1.3.3</span> + </dd> +@@ -915,7 +915,7 @@ + excluding vCPUs). A domain with <code>emulator_quota</code> as any negative + value indicates that the domain has infinite bandwidth for emulator threads + (those excluding vCPUs), which means that it is not bandwidth controlled. +- The value should be in range [1000, 18446744073709551] or less than 0. A ++ The value should be in range [1000, 17592186044415] or less than 0. A + quota with value 0 means no value. + <span class="since">Only QEMU driver support since 0.10.0</span> + </dd> +@@ -937,7 +937,7 @@ + <code>iothread_quota</code> as any negative value indicates that the + domain IOThreads have infinite bandwidth, which means that it is + not bandwidth controlled. The value should be in range +- [1000, 18446744073709551] or less than 0. An <code>iothread_quota</code> ++ [1000, 17592186044415] or less than 0. An <code>iothread_quota</code> + with value 0 means no value. You can use this feature to ensure that + all IOThreads run at the same speed. + <span class="since">Only QEMU driver support since 2.1.0</span> +diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst +index 0804465d44..a5b95c1123 100644 +--- a/docs/manpages/virsh.rst ++++ b/docs/manpages/virsh.rst +@@ -3715,7 +3715,7 @@ XEN_CREDIT scheduler. + ``Note``: The vcpu_period, emulator_period, and iothread_period parameters + have a valid value range of 1000-1000000 or 0, and the vcpu_quota, + emulator_quota, and iothread_quota parameters have a valid value range of +-1000-18446744073709551 or less than 0. The value 0 for ++1000-17592186044415 or less than 0. The value 0 for + either parameter is the same as not specifying that parameter. + + +diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng +index 4a42cb9b40..6671ef3dfa 100644 +--- a/docs/schemas/domaincommon.rng ++++ b/docs/schemas/domaincommon.rng +@@ -6649,7 +6649,7 @@ + <define name="cpuquota"> + <data type="long"> + <param name="pattern">-?[0-9]+</param> +- <param name="maxInclusive">18446744073709551</param> ++ <param name="maxInclusive">17592186044415</param> + <param name='minInclusive'>-1</param> + </data> + </define> +-- +2.30.0 + diff --git a/SOURCES/libvirt-domain_validate-use-defines-for-cpu-period-and-quota-limits.patch b/SOURCES/libvirt-domain_validate-use-defines-for-cpu-period-and-quota-limits.patch new file mode 100644 index 0000000..e293dd5 --- /dev/null +++ b/SOURCES/libvirt-domain_validate-use-defines-for-cpu-period-and-quota-limits.patch @@ -0,0 +1,85 @@ +From 499e3eb6bdca10a5fac9279261e32e64c28273bd Mon Sep 17 00:00:00 2001 +Message-Id: <499e3eb6bdca10a5fac9279261e32e64c28273bd@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Thu, 4 Mar 2021 12:57:55 +0100 +Subject: [PATCH] domain_validate: use defines for cpu period and quota limits +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commints <bc760f4d7c4f964fadcb2a73e126b0053e7a9b06> and +<98a09ca48ed4fc011abf2aa290e02ce1b8f1bb5f> fixed the code to use +defines instead of magic numbers but missed this place. + +Following commit <ed1ba69f5a8132f8c1e73d2a1f142d70de0b564a> changed +the cpu quota limit to reflect what kernel actually allows so using +the defines fixes XML validations as well. + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit 22cae2ea4bad7e285ba19d536bd475f8b00841f8) + +Conflicts: + src/conf/domain_validate.c + - not present in downstream, the code is still part of + domain_conf.c + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <63a44700876e2bd59f276fcd8395abaff011b4c1.1614858616.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/conf/domain_conf.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 166c3e48d2..9f6cdb0de8 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -34,6 +34,7 @@ + #include "domain_addr.h" + #include "domain_conf.h" + #include "snapshot_conf.h" ++#include "vircgroup.h" + #include "viralloc.h" + #include "virxml.h" + #include "viruuid.h" +@@ -6997,10 +6998,13 @@ virDomainDefLifecycleActionValidate(const virDomainDef *def) + #define CPUTUNE_VALIDATE_PERIOD(name) \ + do { \ + if (def->cputune.name > 0 && \ +- (def->cputune.name < 1000 || def->cputune.name > 1000000)) { \ ++ (def->cputune.name < VIR_CGROUP_CPU_PERIOD_MIN || \ ++ def->cputune.name > VIR_CGROUP_CPU_PERIOD_MAX)) { \ + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \ +- _("Value of cputune '%s' must be in range " \ +- "[1000, 1000000]"), #name); \ ++ _("Value of cputune '%s' must be in range [%llu, %llu]"), \ ++ #name, \ ++ VIR_CGROUP_CPU_PERIOD_MIN, \ ++ VIR_CGROUP_CPU_PERIOD_MAX); \ + return -1; \ + } \ + } while (0) +@@ -7008,11 +7012,13 @@ virDomainDefLifecycleActionValidate(const virDomainDef *def) + #define CPUTUNE_VALIDATE_QUOTA(name) \ + do { \ + if (def->cputune.name > 0 && \ +- (def->cputune.name < 1000 || \ +- def->cputune.name > 18446744073709551LL)) { \ ++ (def->cputune.name < VIR_CGROUP_CPU_QUOTA_MIN || \ ++ def->cputune.name > VIR_CGROUP_CPU_QUOTA_MAX)) { \ + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \ +- _("Value of cputune '%s' must be in range " \ +- "[1000, 18446744073709551]"), #name); \ ++ _("Value of cputune '%s' must be in range [%llu, %llu]"), \ ++ #name, \ ++ VIR_CGROUP_CPU_QUOTA_MIN, \ ++ VIR_CGROUP_CPU_QUOTA_MAX); \ + return -1; \ + } \ + } while (0) +-- +2.30.0 + diff --git a/SOURCES/libvirt-network-be-more-verbose-about-the-reason-for-a-firewall-reload.patch b/SOURCES/libvirt-network-be-more-verbose-about-the-reason-for-a-firewall-reload.patch new file mode 100644 index 0000000..4499c36 --- /dev/null +++ b/SOURCES/libvirt-network-be-more-verbose-about-the-reason-for-a-firewall-reload.patch @@ -0,0 +1,57 @@ +From 3a0200ee7544307a9708a6e876603425647bad34 Mon Sep 17 00:00:00 2001 +Message-Id: <3a0200ee7544307a9708a6e876603425647bad34@dist-git> +From: Laine Stump <laine@redhat.com> +Date: Fri, 15 Jan 2021 22:51:48 -0500 +Subject: [PATCH] network: be more verbose about the reason for a firewall + reload + +https://bugzilla.redhat.com/1607929 + +Signed-off-by: Laine Stump <laine@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit c102bbd3efc358fb44fa2bb37fb0bcbeaaab72a5) + +Conflicts: src/network/bridge_driver.c: + some minor things due to upstream switch to using glib for DBus +Signed-off-by: Laine Stump <laine@redhat.com> +Message-Id: <20210116035151.1066734-6-laine@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/network/bridge_driver.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c +index c9c45df758..5995396f78 100644 +--- a/src/network/bridge_driver.c ++++ b/src/network/bridge_driver.c +@@ -665,6 +665,7 @@ firewalld_dbus_filter_bridge(DBusConnection *connection G_GNUC_UNUSED, + if (dbus_message_is_signal(message, + "org.fedoraproject.FirewallD1", "Reloaded")) { + reload = true; ++ VIR_DEBUG("Reload in bridge_driver because of 'Reloaded' signal"); + + } else if (dbus_message_is_signal(message, + DBUS_INTERFACE_DBUS, "NameOwnerChanged")) { +@@ -681,14 +682,15 @@ firewalld_dbus_filter_bridge(DBusConnection *connection G_GNUC_UNUSED, + * if new_owner is empty, firewalld is shutting down. If it is + * non-empty, then it is starting + */ +- if (new_owner && *new_owner) ++ if (new_owner && *new_owner) { ++ VIR_DEBUG("Reload in bridge_driver because of 'NameOwnerChanged' signal, new owner is: '%s'", ++ new_owner); + reload = true; ++ } + } + +- if (reload) { +- VIR_DEBUG("Reload in bridge_driver because of firewalld."); ++ if (reload) + networkReloadFirewallRules(driver, false); +- } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } +-- +2.30.0 + diff --git a/SOURCES/libvirt-node_device-detect-CSS-devices.patch b/SOURCES/libvirt-node_device-detect-CSS-devices.patch new file mode 100644 index 0000000..a25595a --- /dev/null +++ b/SOURCES/libvirt-node_device-detect-CSS-devices.patch @@ -0,0 +1,261 @@ +From 7604b24349c47ff008b1366eb19fc2959614fb71 Mon Sep 17 00:00:00 2001 +Message-Id: <7604b24349c47ff008b1366eb19fc2959614fb71@dist-git> +From: Boris Fiuczynski <fiuczy@linux.ibm.com> +Date: Thu, 8 Oct 2020 11:06:57 -0400 +Subject: [PATCH] node_device: detect CSS devices + +Make channel subsystem (CSS) devices available in the node_device driver. +The CCS devices reside in the computer system and provide CCW devices, e.g.: + + +- css_0_0_003a + | + +- ccw_0_0_1a2b + | + +- scsi_host0 + | + +- scsi_target0_0_0 + | + +- scsi_0_0_0_0 + +Reviewed-by: Erik Skultety <eskultet@redhat.com> +Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> +Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> +(cherry picked from commit 05e6cdafa6e083a1d83e1f2e34b6472c60cc67ac) +https://bugzilla.redhat.com/show_bug.cgi?id=1853289 +https://bugzilla.redhat.com/show_bug.cgi?id=1865932 +Message-Id: <20201008150700.52157-3-bfiuczyn@redhat.com> +Reviewed-by: Erik Skultety <eskultet@redhat.com> +--- + docs/schemas/nodedev.rng | 16 ++++++++++++++ + src/conf/node_device_conf.c | 5 +++++ + src/conf/node_device_conf.h | 1 + + src/conf/virnodedeviceobj.c | 1 + + src/node_device/node_device_udev.c | 22 +++++++++++++++++++ + .../ccw_0_0_10000-invalid.xml | 4 ++-- + tests/nodedevschemadata/ccw_0_0_ffff.xml | 4 ++-- + tests/nodedevschemadata/css_0_0_ffff.xml | 10 +++++++++ + tests/nodedevxml2xmltest.c | 1 + + tools/virsh-nodedev.c | 1 + + 10 files changed, 61 insertions(+), 4 deletions(-) + create mode 100644 tests/nodedevschemadata/css_0_0_ffff.xml + +diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng +index fe6ffa0b53..6ac5804bfb 100644 +--- a/docs/schemas/nodedev.rng ++++ b/docs/schemas/nodedev.rng +@@ -85,6 +85,7 @@ + <ref name="capdrm"/> + <ref name="capmdev"/> + <ref name="capccwdev"/> ++ <ref name="capcssdev"/> + </choice> + </element> + </define> +@@ -651,6 +652,21 @@ + </element> + </define> + ++ <define name='capcssdev'> ++ <attribute name='type'> ++ <value>css</value> ++ </attribute> ++ <element name='cssid'> ++ <ref name='ccwCssidRange'/> ++ </element> ++ <element name='ssid'> ++ <ref name='ccwSsidRange'/> ++ </element> ++ <element name='devno'> ++ <ref name='ccwDevnoRange'/> ++ </element> ++ </define> ++ + <define name='address'> + <element name='address'> + <attribute name='domain'><ref name='hexuint'/></attribute> +diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c +index 4cf5b6e3d7..0a34faa29a 100644 +--- a/src/conf/node_device_conf.c ++++ b/src/conf/node_device_conf.c +@@ -65,6 +65,7 @@ VIR_ENUM_IMPL(virNodeDevCap, + "mdev_types", + "mdev", + "ccw", ++ "css", + ); + + VIR_ENUM_IMPL(virNodeDevNetCap, +@@ -588,6 +589,7 @@ virNodeDeviceDefFormat(const virNodeDeviceDef *def) + data->mdev.iommuGroupNumber); + break; + case VIR_NODE_DEV_CAP_CCW_DEV: ++ case VIR_NODE_DEV_CAP_CSS_DEV: + virBufferAsprintf(&buf, "<cssid>0x%x</cssid>\n", + data->ccw_dev.cssid); + virBufferAsprintf(&buf, "<ssid>0x%x</ssid>\n", +@@ -1893,6 +1895,7 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt, + ret = virNodeDevCapMdevParseXML(ctxt, def, node, &caps->data.mdev); + break; + case VIR_NODE_DEV_CAP_CCW_DEV: ++ case VIR_NODE_DEV_CAP_CSS_DEV: + ret = virNodeDevCapCCWParseXML(ctxt, def, node, &caps->data.ccw_dev); + break; + case VIR_NODE_DEV_CAP_MDEV_TYPES: +@@ -2211,6 +2214,7 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) + case VIR_NODE_DEV_CAP_FC_HOST: + case VIR_NODE_DEV_CAP_VPORTS: + case VIR_NODE_DEV_CAP_CCW_DEV: ++ case VIR_NODE_DEV_CAP_CSS_DEV: + case VIR_NODE_DEV_CAP_LAST: + /* This case is here to shutup the compiler */ + break; +@@ -2264,6 +2268,7 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def) + case VIR_NODE_DEV_CAP_MDEV_TYPES: + case VIR_NODE_DEV_CAP_MDEV: + case VIR_NODE_DEV_CAP_CCW_DEV: ++ case VIR_NODE_DEV_CAP_CSS_DEV: + case VIR_NODE_DEV_CAP_LAST: + break; + } +diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h +index bf7939fbb3..19ea3fc7c2 100644 +--- a/src/conf/node_device_conf.h ++++ b/src/conf/node_device_conf.h +@@ -65,6 +65,7 @@ typedef enum { + VIR_NODE_DEV_CAP_MDEV_TYPES, /* Device capable of mediated devices */ + VIR_NODE_DEV_CAP_MDEV, /* Mediated device */ + VIR_NODE_DEV_CAP_CCW_DEV, /* s390 CCW device */ ++ VIR_NODE_DEV_CAP_CSS_DEV, /* s390 channel subsystem device */ + + VIR_NODE_DEV_CAP_LAST + } virNodeDevCapType; +diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c +index 3a34a324ca..8c8ffd6d24 100644 +--- a/src/conf/virnodedeviceobj.c ++++ b/src/conf/virnodedeviceobj.c +@@ -676,6 +676,7 @@ virNodeDeviceObjHasCap(const virNodeDeviceObj *obj, + case VIR_NODE_DEV_CAP_MDEV_TYPES: + case VIR_NODE_DEV_CAP_MDEV: + case VIR_NODE_DEV_CAP_CCW_DEV: ++ case VIR_NODE_DEV_CAP_CSS_DEV: + case VIR_NODE_DEV_CAP_LAST: + break; + } +diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c +index 9667a042bd..efe3cebd6a 100644 +--- a/src/node_device/node_device_udev.c ++++ b/src/node_device/node_device_udev.c +@@ -1097,6 +1097,24 @@ udevProcessCCW(struct udev_device *device, + } + + ++static int ++udevProcessCSS(struct udev_device *device, ++ virNodeDeviceDefPtr def) ++{ ++ /* only process IO subchannel and vfio-ccw devices to keep the list sane */ ++ if (STRNEQ(def->driver, "io_subchannel") && ++ STRNEQ(def->driver, "vfio_ccw")) ++ return -1; ++ ++ if (udevGetCCWAddress(def->sysfs_path, &def->caps->data) < 0) ++ return -1; ++ ++ if (udevGenerateDeviceName(device, def, NULL) != 0) ++ return -1; ++ ++ return 0; ++} ++ + static int + udevGetDeviceNodes(struct udev_device *device, + virNodeDeviceDefPtr def) +@@ -1175,6 +1193,8 @@ udevGetDeviceType(struct udev_device *device, + *type = VIR_NODE_DEV_CAP_MDEV; + else if (STREQ_NULLABLE(subsystem, "ccw")) + *type = VIR_NODE_DEV_CAP_CCW_DEV; ++ else if (STREQ_NULLABLE(subsystem, "css")) ++ *type = VIR_NODE_DEV_CAP_CSS_DEV; + + VIR_FREE(subsystem); + } +@@ -1219,6 +1239,8 @@ udevGetDeviceDetails(struct udev_device *device, + return udevProcessMediatedDevice(device, def); + case VIR_NODE_DEV_CAP_CCW_DEV: + return udevProcessCCW(device, def); ++ case VIR_NODE_DEV_CAP_CSS_DEV: ++ return udevProcessCSS(device, def); + case VIR_NODE_DEV_CAP_MDEV_TYPES: + case VIR_NODE_DEV_CAP_SYSTEM: + case VIR_NODE_DEV_CAP_FC_HOST: +diff --git a/tests/nodedevschemadata/ccw_0_0_10000-invalid.xml b/tests/nodedevschemadata/ccw_0_0_10000-invalid.xml +index d840555c09..f3cf0c1c66 100644 +--- a/tests/nodedevschemadata/ccw_0_0_10000-invalid.xml ++++ b/tests/nodedevschemadata/ccw_0_0_10000-invalid.xml +@@ -1,7 +1,7 @@ + <device> + <name>ccw_0_0_10000</name> +- <path>/sys/devices/css0/0.0.0000/0.0.10000</path> +- <parent>computer</parent> ++ <path>/sys/devices/css0/0.0.0070/0.0.10000</path> ++ <parent>css_0_0_0070</parent> + <capability type='ccw'> + <cssid>0x0</cssid> + <ssid>0x0</ssid> +diff --git a/tests/nodedevschemadata/ccw_0_0_ffff.xml b/tests/nodedevschemadata/ccw_0_0_ffff.xml +index 5ecd0b0aae..3b8ea46e37 100644 +--- a/tests/nodedevschemadata/ccw_0_0_ffff.xml ++++ b/tests/nodedevschemadata/ccw_0_0_ffff.xml +@@ -1,7 +1,7 @@ + <device> + <name>ccw_0_0_ffff</name> +- <path>/sys/devices/css0/0.0.0000/0.0.ffff</path> +- <parent>computer</parent> ++ <path>/sys/devices/css0/0.0.0070/0.0.ffff</path> ++ <parent>css_0_0_0070</parent> + <capability type='ccw'> + <cssid>0x0</cssid> + <ssid>0x0</ssid> +diff --git a/tests/nodedevschemadata/css_0_0_ffff.xml b/tests/nodedevschemadata/css_0_0_ffff.xml +new file mode 100644 +index 0000000000..312e07fe65 +--- /dev/null ++++ b/tests/nodedevschemadata/css_0_0_ffff.xml +@@ -0,0 +1,10 @@ ++<device> ++ <name>css_0_0_ffff</name> ++ <path>/sys/devices/css0/0.0.ffff</path> ++ <parent>computer</parent> ++ <capability type='css'> ++ <cssid>0x0</cssid> ++ <ssid>0x0</ssid> ++ <devno>0xffff</devno> ++ </capability> ++</device> +diff --git a/tests/nodedevxml2xmltest.c b/tests/nodedevxml2xmltest.c +index 6168c29c70..3cb23b1df4 100644 +--- a/tests/nodedevxml2xmltest.c ++++ b/tests/nodedevxml2xmltest.c +@@ -123,6 +123,7 @@ mymain(void) + DO_TEST("pci_0000_02_10_7_mdev_types"); + DO_TEST("mdev_3627463d_b7f0_4fea_b468_f1da537d301b"); + DO_TEST("ccw_0_0_ffff"); ++ DO_TEST("css_0_0_ffff"); + + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + } +diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c +index cb2fc26d1a..26b3acc608 100644 +--- a/tools/virsh-nodedev.c ++++ b/tools/virsh-nodedev.c +@@ -461,6 +461,7 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED) + case VIR_NODE_DEV_CAP_CCW_DEV: + flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV; + break; ++ case VIR_NODE_DEV_CAP_CSS_DEV: + case VIR_NODE_DEV_CAP_LAST: + break; + } +-- +2.28.0 + diff --git a/SOURCES/libvirt-node_device-detect-DASD-devices.patch b/SOURCES/libvirt-node_device-detect-DASD-devices.patch new file mode 100644 index 0000000..626d59f --- /dev/null +++ b/SOURCES/libvirt-node_device-detect-DASD-devices.patch @@ -0,0 +1,76 @@ +From c83c1121508cc4283f372789398a909146803b72 Mon Sep 17 00:00:00 2001 +Message-Id: <c83c1121508cc4283f372789398a909146803b72@dist-git> +From: Boris Fiuczynski <fiuczy@linux.ibm.com> +Date: Thu, 8 Oct 2020 11:06:59 -0400 +Subject: [PATCH] node_device: detect DASD devices + +Make Direct Access Storage Devices (DASDs) available in the node_device driver. + +Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> +Reviewed-by: Erik Skultety <eskultet@redhat.com> +Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> +(cherry picked from commit 33bbf589dd739c48ff20d2120e8c4018d241d32f) +https://bugzilla.redhat.com/show_bug.cgi?id=1853289 +https://bugzilla.redhat.com/show_bug.cgi?id=1865932 +Message-Id: <20201008150700.52157-5-bfiuczyn@redhat.com> +Reviewed-by: Erik Skultety <eskultet@redhat.com> +--- + src/node_device/node_device_udev.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c +index efe3cebd6a..b6b28bc35a 100644 +--- a/src/node_device/node_device_udev.c ++++ b/src/node_device/node_device_udev.c +@@ -870,6 +870,19 @@ udevProcessSD(struct udev_device *device, + } + + ++static int ++udevProcessDASD(struct udev_device *device, ++ virNodeDeviceDefPtr def) ++{ ++ virNodeDevCapStoragePtr storage = &def->caps->data.storage; ++ ++ if (udevGetStringSysfsAttr(device, "device/uid", &storage->serial) < 0) ++ return -1; ++ ++ return udevProcessDisk(device, def); ++} ++ ++ + /* This function exists to deal with the case in which a driver does + * not provide a device type in the usual place, but udev told us it's + * a storage device, and we can make a good guess at what kind of +@@ -890,6 +903,19 @@ udevKludgeStorageType(virNodeDeviceDefPtr def) + def->sysfs_path); + return 0; + } ++ ++ /* For Direct Access Storage Devices (DASDs) there are ++ * currently no identifiers in udev besides ID_PATH. Since ++ * ID_TYPE=disk does not exist on DASDs they fall through ++ * the udevProcessStorage detection logic. */ ++ if (STRPREFIX(def->caps->data.storage.block, "/dev/dasd")) { ++ def->caps->data.storage.drive_type = g_strdup("dasd"); ++ VIR_DEBUG("Found storage type '%s' for device " ++ "with sysfs path '%s'", ++ def->caps->data.storage.drive_type, ++ def->sysfs_path); ++ return 0; ++ } + VIR_DEBUG("Could not determine storage type " + "for device with sysfs path '%s'", def->sysfs_path); + return -1; +@@ -977,6 +1003,8 @@ udevProcessStorage(struct udev_device *device, + ret = udevProcessFloppy(device, def); + } else if (STREQ(def->caps->data.storage.drive_type, "sd")) { + ret = udevProcessSD(device, def); ++ } else if (STREQ(def->caps->data.storage.drive_type, "dasd")) { ++ ret = udevProcessDASD(device, def); + } else { + VIR_DEBUG("Unsupported storage type '%s'", + def->caps->data.storage.drive_type); +-- +2.28.0 + diff --git a/SOURCES/libvirt-node_device-refactor-udevProcessCCW.patch b/SOURCES/libvirt-node_device-refactor-udevProcessCCW.patch new file mode 100644 index 0000000..1b6621c --- /dev/null +++ b/SOURCES/libvirt-node_device-refactor-udevProcessCCW.patch @@ -0,0 +1,76 @@ +From a89df2d899e6e93ab7bccdaa1afb130d01d9b286 Mon Sep 17 00:00:00 2001 +Message-Id: <a89df2d899e6e93ab7bccdaa1afb130d01d9b286@dist-git> +From: Boris Fiuczynski <fiuczy@linux.ibm.com> +Date: Thu, 8 Oct 2020 11:06:56 -0400 +Subject: [PATCH] node_device: refactor udevProcessCCW + +Refactor out CCW address parsing for later reuse. + +Reviewed-by: Erik Skultety <eskultet@redhat.com> +Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> +Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> +(cherry picked from commit 0e7f8bb6c1c3a63cf892f7afcd34fcb979ef0155) +https://bugzilla.redhat.com/show_bug.cgi?id=1853289 +https://bugzilla.redhat.com/show_bug.cgi?id=1865932 +Message-Id: <20201008150700.52157-2-bfiuczyn@redhat.com> +Reviewed-by: Erik Skultety <eskultet@redhat.com> +--- + src/node_device/node_device_udev.c | 31 ++++++++++++++++++++---------- + 1 file changed, 21 insertions(+), 10 deletions(-) + +diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c +index ae3d081e66..9667a042bd 100644 +--- a/src/node_device/node_device_udev.c ++++ b/src/node_device/node_device_udev.c +@@ -1058,27 +1058,38 @@ udevProcessMediatedDevice(struct udev_device *dev, + + + static int +-udevProcessCCW(struct udev_device *device, +- virNodeDeviceDefPtr def) ++udevGetCCWAddress(const char *sysfs_path, ++ virNodeDevCapDataPtr data) + { +- int online; + char *p; +- virNodeDevCapDataPtr data = &def->caps->data; +- +- /* process only online devices to keep the list sane */ +- if (udevGetIntSysfsAttr(device, "online", &online, 0) < 0 || online != 1) +- return -1; + +- if ((p = strrchr(def->sysfs_path, '/')) == NULL || ++ if ((p = strrchr(sysfs_path, '/')) == NULL || + virStrToLong_ui(p + 1, &p, 16, &data->ccw_dev.cssid) < 0 || p == NULL || + virStrToLong_ui(p + 1, &p, 16, &data->ccw_dev.ssid) < 0 || p == NULL || + virStrToLong_ui(p + 1, &p, 16, &data->ccw_dev.devno) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to parse the CCW address from sysfs path: '%s'"), +- def->sysfs_path); ++ sysfs_path); + return -1; + } + ++ return 0; ++} ++ ++ ++static int ++udevProcessCCW(struct udev_device *device, ++ virNodeDeviceDefPtr def) ++{ ++ int online; ++ ++ /* process only online devices to keep the list sane */ ++ if (udevGetIntSysfsAttr(device, "online", &online, 0) < 0 || online != 1) ++ return -1; ++ ++ if (udevGetCCWAddress(def->sysfs_path, &def->caps->data) < 0) ++ return -1; ++ + if (udevGenerateDeviceName(device, def, NULL) != 0) + return -1; + +-- +2.28.0 + diff --git a/SOURCES/libvirt-numa-expose-HMAT-APIs.patch b/SOURCES/libvirt-numa-expose-HMAT-APIs.patch new file mode 100644 index 0000000..08b3549 --- /dev/null +++ b/SOURCES/libvirt-numa-expose-HMAT-APIs.patch @@ -0,0 +1,242 @@ +From f2670434261a395acfe97a9bd93bd55c6b3fb1f2 Mon Sep 17 00:00:00 2001 +Message-Id: <f2670434261a395acfe97a9bd93bd55c6b3fb1f2@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Wed, 7 Oct 2020 18:45:41 +0200 +Subject: [PATCH] numa: expose HMAT APIs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These APIs will be used by QEMU driver when building the command +line. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit 11d8ca9794e80224d0634d67da86a20380c22ab5) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Conflicts: +- src/conf/numa_conf.c: +- src/conf/numa_conf.h: Both are context. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <ad394e2359bfbbff4c9d61ac2bf5faca1eba5943.1602087923.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/conf/numa_conf.c | 139 +++++++++++++++++++++++++++++++++++++++ + src/conf/numa_conf.h | 28 ++++++++ + src/libvirt_private.syms | 6 ++ + 3 files changed, 173 insertions(+) + +diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c +index c90fb01bb6..277a695d84 100644 +--- a/src/conf/numa_conf.c ++++ b/src/conf/numa_conf.c +@@ -1800,3 +1800,142 @@ virDomainNumaGetMemorySize(virDomainNumaPtr numa) + + return ret; + } ++ ++ ++bool ++virDomainNumaHasHMAT(const virDomainNuma *numa) ++{ ++ size_t i; ++ ++ if (!numa) ++ return false; ++ ++ if (numa->ninterconnects) ++ return true; ++ ++ for (i = 0; i < numa->nmem_nodes; i++) { ++ if (numa->mem_nodes[i].ncaches) ++ return true; ++ } ++ ++ return false; ++} ++ ++ ++size_t ++virDomainNumaGetNodeCacheCount(const virDomainNuma *numa, ++ size_t node) ++{ ++ if (!numa || node >= numa->nmem_nodes) ++ return 0; ++ ++ return numa->mem_nodes[node].ncaches; ++} ++ ++ ++int ++virDomainNumaGetNodeCache(const virDomainNuma *numa, ++ size_t node, ++ size_t cache, ++ unsigned int *level, ++ unsigned int *size, ++ unsigned int *line, ++ virDomainCacheAssociativity *associativity, ++ virDomainCachePolicy *policy) ++{ ++ const virDomainNumaNode *cell; ++ ++ if (!numa || node >= numa->nmem_nodes) ++ return -1; ++ ++ cell = &numa->mem_nodes[node]; ++ ++ if (cache >= cell->ncaches) ++ return -1; ++ ++ *level = cell->caches[cache].level; ++ *size = cell->caches[cache].size; ++ *line = cell->caches[cache].line; ++ *associativity = cell->caches[cache].associativity; ++ *policy = cell->caches[cache].policy; ++ return 0; ++} ++ ++ ++ssize_t ++virDomainNumaGetNodeInitiator(const virDomainNuma *numa, ++ size_t node) ++{ ++ size_t i; ++ unsigned int maxBandwidth = 0; ++ ssize_t candidateBandwidth = -1; ++ unsigned int minLatency = UINT_MAX; ++ ssize_t candidateLatency = -1; ++ ++ if (!numa || node >= numa->nmem_nodes) ++ return -1; ++ ++ for (i = 0; i < numa->ninterconnects; i++) { ++ const virDomainNumaInterconnect *l = &numa->interconnects[i]; ++ ++ if (l->target != node) ++ continue; ++ ++ switch (l->type) { ++ case VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_LATENCY: ++ if (l->value < minLatency) { ++ minLatency = l->value; ++ candidateLatency = l->initiator; ++ } ++ break; ++ ++ case VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_BANDWIDTH: ++ if (l->value > maxBandwidth) { ++ maxBandwidth = l->value; ++ candidateBandwidth = l->initiator; ++ } ++ break; ++ } ++ } ++ ++ if (candidateLatency >= 0) ++ return candidateLatency; ++ ++ return candidateBandwidth; ++} ++ ++ ++size_t ++virDomainNumaGetInterconnectsCount(const virDomainNuma *numa) ++{ ++ if (!numa) ++ return 0; ++ ++ return numa->ninterconnects; ++} ++ ++ ++int ++virDomainNumaGetInterconnect(const virDomainNuma *numa, ++ size_t i, ++ virDomainNumaInterconnectType *type, ++ unsigned int *initiator, ++ unsigned int *target, ++ unsigned int *cache, ++ virDomainMemoryLatency *accessType, ++ unsigned long *value) ++{ ++ const virDomainNumaInterconnect *l; ++ ++ if (!numa || i >= numa->ninterconnects) ++ return -1; ++ ++ l = &numa->interconnects[i]; ++ *type = l->type; ++ *initiator = l->initiator; ++ *target = l->target; ++ *cache = l->cache; ++ *accessType = l->accessType; ++ *value = l->value; ++ return 0; ++} +diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h +index 2963004c94..63843a1cc6 100644 +--- a/src/conf/numa_conf.h ++++ b/src/conf/numa_conf.h +@@ -220,3 +220,31 @@ int virDomainNumaDefFormatXML(virBufferPtr buf, virDomainNumaPtr def); + int virDomainNumaDefValidate(const virDomainNuma *def); + + unsigned int virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa); ++ ++bool virDomainNumaHasHMAT(const virDomainNuma *numa); ++ ++size_t virDomainNumaGetNodeCacheCount(const virDomainNuma *numa, ++ size_t node); ++ ++int virDomainNumaGetNodeCache(const virDomainNuma *numa, ++ size_t node, ++ size_t cache, ++ unsigned int *level, ++ unsigned int *size, ++ unsigned int *line, ++ virDomainCacheAssociativity *associativity, ++ virDomainCachePolicy *policy); ++ ++ssize_t virDomainNumaGetNodeInitiator(const virDomainNuma *numa, ++ size_t node); ++ ++size_t virDomainNumaGetInterconnectsCount(const virDomainNuma *numa); ++ ++int virDomainNumaGetInterconnect(const virDomainNuma *numa, ++ size_t i, ++ virDomainNumaInterconnectType *type, ++ unsigned int *initiator, ++ unsigned int *target, ++ unsigned int *cache, ++ virDomainMemoryLatency *accessType, ++ unsigned long *value); +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index de95e3b116..fdd104cd25 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -820,14 +820,20 @@ virDomainNumaCheckABIStability; + virDomainNumaEquals; + virDomainNumaFree; + virDomainNumaGetCPUCountTotal; ++virDomainNumaGetInterconnect; ++virDomainNumaGetInterconnectsCount; + virDomainNumaGetMaxCPUID; + virDomainNumaGetMemorySize; ++virDomainNumaGetNodeCache; ++virDomainNumaGetNodeCacheCount; + virDomainNumaGetNodeCount; + virDomainNumaGetNodeCpumask; + virDomainNumaGetNodeDiscard; + virDomainNumaGetNodeDistance; ++virDomainNumaGetNodeInitiator; + virDomainNumaGetNodeMemoryAccessMode; + virDomainNumaGetNodeMemorySize; ++virDomainNumaHasHMAT; + virDomainNumaNew; + virDomainNumaNodeDistanceIsUsingDefaults; + virDomainNumaNodesDistancesAreBeingSet; +-- +2.29.2 + diff --git a/SOURCES/libvirt-numa_conf-Drop-CPU-from-name-of-two-functions.patch b/SOURCES/libvirt-numa_conf-Drop-CPU-from-name-of-two-functions.patch new file mode 100644 index 0000000..2974deb --- /dev/null +++ b/SOURCES/libvirt-numa_conf-Drop-CPU-from-name-of-two-functions.patch @@ -0,0 +1,102 @@ +From c049804bc3b296a183ce0bd819d5f9b1d1a45ea7 Mon Sep 17 00:00:00 2001 +Message-Id: <c049804bc3b296a183ce0bd819d5f9b1d1a45ea7@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Wed, 7 Oct 2020 18:45:34 +0200 +Subject: [PATCH] numa_conf: Drop CPU from name of two functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There are two functions virDomainNumaDefCPUFormatXML() and +virDomainNumaDefCPUParseXML() which format and parse domain's +<numa/>. There is nothing CPU specific about them. Drop the +infix. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit 68c5b0183cb157c4672a6af3a14375df4434cee5) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Conflicts: +- src/conf/domain_conf.c: Context. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <a06547d5b53c7a8fa2a2801a9cbd7a47834ebaa3.1602087923.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/conf/cpu_conf.c | 2 +- + src/conf/domain_conf.c | 2 +- + src/conf/numa_conf.c | 8 ++++---- + src/conf/numa_conf.h | 4 ++-- + 4 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c +index 1a2948ce11..dfd0c1f798 100644 +--- a/src/conf/cpu_conf.c ++++ b/src/conf/cpu_conf.c +@@ -746,7 +746,7 @@ virCPUDefFormatBufFull(virBufferPtr buf, + if (virCPUDefFormatBuf(&childrenBuf, def) < 0) + goto cleanup; + +- if (virDomainNumaDefCPUFormatXML(&childrenBuf, numa) < 0) ++ if (virDomainNumaDefFormatXML(&childrenBuf, numa) < 0) + goto cleanup; + + /* Put it all together */ +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 484f3b4352..3229d5ec95 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -20487,7 +20487,7 @@ virDomainDefParseXML(xmlDocPtr xml, + if (virCPUDefParseXML(ctxt, "./cpu[1]", VIR_CPU_TYPE_GUEST, &def->cpu) < 0) + goto error; + +- if (virDomainNumaDefCPUParseXML(def->numa, ctxt) < 0) ++ if (virDomainNumaDefParseXML(def->numa, ctxt) < 0) + goto error; + + if (virDomainNumaGetCPUCountTotal(def->numa) > virDomainDefGetVcpusMax(def)) { +diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c +index 6f1257fd8e..38fcf9d9aa 100644 +--- a/src/conf/numa_conf.c ++++ b/src/conf/numa_conf.c +@@ -842,8 +842,8 @@ virDomainNumaDefNodeDistanceParseXML(virDomainNumaPtr def, + } + + int +-virDomainNumaDefCPUParseXML(virDomainNumaPtr def, +- xmlXPathContextPtr ctxt) ++virDomainNumaDefParseXML(virDomainNumaPtr def, ++ xmlXPathContextPtr ctxt) + { + xmlNodePtr *nodes = NULL; + xmlNodePtr oldNode = ctxt->node; +@@ -971,8 +971,8 @@ virDomainNumaDefCPUParseXML(virDomainNumaPtr def, + + + int +-virDomainNumaDefCPUFormatXML(virBufferPtr buf, +- virDomainNumaPtr def) ++virDomainNumaDefFormatXML(virBufferPtr buf, ++ virDomainNumaPtr def) + { + virDomainMemoryAccess memAccess; + virTristateBool discard; +diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h +index b1b8e3274d..ce865cbfbb 100644 +--- a/src/conf/numa_conf.h ++++ b/src/conf/numa_conf.h +@@ -182,7 +182,7 @@ bool virDomainNumatuneNodesetIsAvailable(virDomainNumaPtr numatune, + bool virDomainNumatuneNodeSpecified(virDomainNumaPtr numatune, + int cellid); + +-int virDomainNumaDefCPUParseXML(virDomainNumaPtr def, xmlXPathContextPtr ctxt); +-int virDomainNumaDefCPUFormatXML(virBufferPtr buf, virDomainNumaPtr def); ++int virDomainNumaDefParseXML(virDomainNumaPtr def, xmlXPathContextPtr ctxt); ++int virDomainNumaDefFormatXML(virBufferPtr buf, virDomainNumaPtr def); + + unsigned int virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa); +-- +2.29.2 + diff --git a/SOURCES/libvirt-numa_conf-Make-virDomainNumaSetNodeCpumask-return-void.patch b/SOURCES/libvirt-numa_conf-Make-virDomainNumaSetNodeCpumask-return-void.patch new file mode 100644 index 0000000..f9c60df --- /dev/null +++ b/SOURCES/libvirt-numa_conf-Make-virDomainNumaSetNodeCpumask-return-void.patch @@ -0,0 +1,87 @@ +From a1af99a1129058f2aa312e3c9d125f5bc7693912 Mon Sep 17 00:00:00 2001 +Message-Id: <a1af99a1129058f2aa312e3c9d125f5bc7693912@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Wed, 7 Oct 2020 18:45:37 +0200 +Subject: [PATCH] numa_conf: Make virDomainNumaSetNodeCpumask() return void +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is only one caller of virDomainNumaSetNodeCpumask() which +checks for the return value but because the function will return +NULL iff the @cpumask was NULL in the first place. But in that +place @cpumask can't be NULL because it was just allocated by +virBitmapParse(). + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit 1050c6beb1f2238cd847d93eab17d658720b08e1) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <8564849f4fc4aaca69eec3d2b7e59d03234ea39f.1602087923.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/conf/numa_conf.c | 4 +--- + src/conf/numa_conf.h | 6 +++--- + src/libxl/xen_xl.c | 4 ++-- + 3 files changed, 6 insertions(+), 8 deletions(-) + +diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c +index 38fcf9d9aa..c9cc8ac22e 100644 +--- a/src/conf/numa_conf.c ++++ b/src/conf/numa_conf.c +@@ -1318,14 +1318,12 @@ virDomainNumaGetNodeCpumask(virDomainNumaPtr numa, + } + + +-virBitmapPtr ++void + virDomainNumaSetNodeCpumask(virDomainNumaPtr numa, + size_t node, + virBitmapPtr cpumask) + { + numa->mem_nodes[node].cpumask = cpumask; +- +- return numa->mem_nodes[node].cpumask; + } + + +diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h +index ce865cbfbb..6808439a7c 100644 +--- a/src/conf/numa_conf.h ++++ b/src/conf/numa_conf.h +@@ -156,9 +156,9 @@ size_t virDomainNumaSetNodeDistanceCount(virDomainNumaPtr numa, + size_t ndistances) + ATTRIBUTE_NONNULL(1); + +-virBitmapPtr virDomainNumaSetNodeCpumask(virDomainNumaPtr numa, +- size_t node, +- virBitmapPtr cpumask) ++void virDomainNumaSetNodeCpumask(virDomainNumaPtr numa, ++ size_t node, ++ virBitmapPtr cpumask) + ATTRIBUTE_NONNULL(1); + + /* +diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c +index 91b1825399..edea30a86a 100644 +--- a/src/libxl/xen_xl.c ++++ b/src/libxl/xen_xl.c +@@ -508,10 +508,10 @@ xenParseXLVnuma(virConfPtr conf, + goto cleanup; + } + +- if ((virBitmapParse(vtoken, &cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0) || +- (virDomainNumaSetNodeCpumask(numa, vnodeCnt, cpumask) == NULL)) ++ if (virBitmapParse(vtoken, &cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0) + goto cleanup; + ++ virDomainNumaSetNodeCpumask(numa, vnodeCnt, cpumask); + vcpus += virBitmapCountBits(cpumask); + + } else if (STRPREFIX(str, "vdistances")) { +-- +2.29.2 + diff --git a/SOURCES/libvirt-numa_conf-Properly-check-for-caches-in-virDomainNumaDefValidate.patch b/SOURCES/libvirt-numa_conf-Properly-check-for-caches-in-virDomainNumaDefValidate.patch new file mode 100644 index 0000000..525beef --- /dev/null +++ b/SOURCES/libvirt-numa_conf-Properly-check-for-caches-in-virDomainNumaDefValidate.patch @@ -0,0 +1,91 @@ +From 8521a431d3da3cc360eb8102eda1c0d649f1ecc3 Mon Sep 17 00:00:00 2001 +Message-Id: <8521a431d3da3cc360eb8102eda1c0d649f1ecc3@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Wed, 7 Oct 2020 18:45:45 +0200 +Subject: [PATCH] numa_conf: Properly check for caches in + virDomainNumaDefValidate() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When adding support for HMAT, in f0611fe8830 I've introduced a +check which aims to validate /domain/cpu/numa/interconnects. As a +part of that, there is a loop which checks whether all <latency/> +with @cache attribute refer to an existing cache level. For +instance: + + <cpu mode='host-model' check='partial'> + <numa> + <cell id='0' cpus='0-5' memory='512000' unit='KiB' discard='yes'> + <cache level='1' associativity='direct' policy='writeback'> + <size value='8' unit='KiB'/> + <line value='5' unit='B'/> + </cache> + </cell> + <interconnects> + <latency initiator='0' target='0' cache='1' type='access' value='5'/> + <bandwidth initiator='0' target='0' type='access' value='204800' unit='KiB'/> + </interconnects> + </numa> + </cpu> + +This XML defines that accessing L1 cache of node #0 from node #0 +has latency of 5ns. + +However, the loop was not written properly. Well, the check in +it, as it was always checking for the first cache in the target +node and not the rest. Therefore, the following example errors +out: + + <cpu mode='host-model' check='partial'> + <numa> + <cell id='0' cpus='0-5' memory='512000' unit='KiB' discard='yes'> + <cache level='3' associativity='direct' policy='writeback'> + <size value='10' unit='KiB'/> + <line value='8' unit='B'/> + </cache> + <cache level='1' associativity='direct' policy='writeback'> + <size value='8' unit='KiB'/> + <line value='5' unit='B'/> + </cache> + </cell> + <interconnects> + <latency initiator='0' target='0' cache='1' type='access' value='5'/> + <bandwidth initiator='0' target='0' type='access' value='204800' unit='KiB'/> + </interconnects> + </numa> + </cpu> + +This errors out even though it is a valid configuration. The L1 +cache under node #0 is still present. + +Fixes: f0611fe8830 +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Laine Stump <laine@redhat.com> +(cherry picked from commit e41ac71fca309b50e2c8e6ec142d8fe1280ca2ad) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <4bb47f9e97ca097cee1259449da4739b55753751.1602087923.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/conf/numa_conf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c +index 5a92eb35cc..a20398714e 100644 +--- a/src/conf/numa_conf.c ++++ b/src/conf/numa_conf.c +@@ -1423,7 +1423,7 @@ virDomainNumaDefValidate(const virDomainNuma *def) + + if (l->cache > 0) { + for (j = 0; j < def->mem_nodes[l->target].ncaches; j++) { +- const virDomainNumaCache *cache = def->mem_nodes[l->target].caches; ++ const virDomainNumaCache *cache = &def->mem_nodes[l->target].caches[j]; + + if (l->cache == cache->level) + break; +-- +2.29.2 + diff --git a/SOURCES/libvirt-qemu-Add-virtio-related-options-to-vsock.patch b/SOURCES/libvirt-qemu-Add-virtio-related-options-to-vsock.patch index a0a2f4d..4b1eab9 100644 --- a/SOURCES/libvirt-qemu-Add-virtio-related-options-to-vsock.patch +++ b/SOURCES/libvirt-qemu-Add-virtio-related-options-to-vsock.patch @@ -1,7 +1,7 @@ -From 1b084c7ff54f1bb36c9e0dee3e1c86a250f3d6af Mon Sep 17 00:00:00 2001 -Message-Id: <1b084c7ff54f1bb36c9e0dee3e1c86a250f3d6af@dist-git> +From 362d106d8897a3982f5eaed0c4bc0194d6f9ef28 Mon Sep 17 00:00:00 2001 +Message-Id: <362d106d8897a3982f5eaed0c4bc0194d6f9ef28@dist-git> From: Boris Fiuczynski <fiuczy@linux.ibm.com> -Date: Tue, 23 Mar 2021 10:25:46 +0100 +Date: Fri, 26 Feb 2021 06:43:35 -0500 Subject: [PATCH] qemu: Add virtio related options to vsock Add virtio related options iommu, ats and packed as driver element attributes @@ -17,7 +17,7 @@ Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com> (cherry picked from commit bd112c9e0f7523b90bf1362cf60deea7db05a32b) -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1941820 +Resolves: https://bugzilla.redhat.com/1931548 Note: since the virtio option packed is not yet available in the code version it will also not be available with this backported patch. @@ -31,9 +31,8 @@ Conflicts: docs/formatdomain.rst: src/qemu/qemu_validate.c: does not exist downstream. can be neglected -Signed-off-by: Thomas Huth <thuth@redhat.com> -Message-Id: <20210323092546.405902-2-thuth@redhat.com> -Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <20210226114335.100390-2-bfiuczyn@redhat.com> +Reviewed-by: Pavel Hrdina <phrdina@redhat.com> --- docs/formatdomain.html.in | 5 ++- docs/schemas/domaincommon.rng | 5 +++ @@ -51,10 +50,10 @@ Reviewed-by: Michal Privoznik <mprivozn@redhat.com> create mode 120000 tests/qemuxml2xmloutdata/vhost-vsock-ccw-iommu.s390x-latest.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in -index 76799f5ffc..c4e4efcde2 100644 +index bec753e37f..127dd13cc0 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in -@@ -9131,7 +9131,10 @@ qemu-kvm -net nic,model=? /dev/null +@@ -9240,7 +9240,10 @@ qemu-kvm -net nic,model=? /dev/null element specifies the CID assigned to the guest. If the attribute <code>auto</code> is set to <code>yes</code>, libvirt will assign a free CID automatically on domain startup. @@ -83,7 +82,7 @@ index 9fda5f17e0..4a42cb9b40 100644 </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c -index 60962ee7c1..4a4cff434b 100644 +index c5a0442c6f..166c3e48d2 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2392,6 +2392,7 @@ virDomainVsockDefFree(virDomainVsockDefPtr vsock) @@ -121,7 +120,7 @@ index 60962ee7c1..4a4cff434b 100644 return 0; } -@@ -16721,6 +16735,11 @@ virDomainVsockDefParseXML(virDomainXMLOptionPtr xmlopt, +@@ -16649,6 +16663,11 @@ virDomainVsockDefParseXML(virDomainXMLOptionPtr xmlopt, if (virDomainDeviceInfoParseXML(xmlopt, node, &vsock->info, flags) < 0) return NULL; @@ -133,7 +132,7 @@ index 60962ee7c1..4a4cff434b 100644 return g_steal_pointer(&vsock); } -@@ -23401,6 +23420,10 @@ virDomainVsockDefCheckABIStability(virDomainVsockDefPtr src, +@@ -23350,6 +23369,10 @@ virDomainVsockDefCheckABIStability(virDomainVsockDefPtr src, return false; } @@ -144,7 +143,7 @@ index 60962ee7c1..4a4cff434b 100644 if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info)) return false; -@@ -28410,6 +28433,7 @@ virDomainVsockDefFormat(virBufferPtr buf, +@@ -28364,6 +28387,7 @@ virDomainVsockDefFormat(virBufferPtr buf, g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf); g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER; g_auto(virBuffer) cidAttrBuf = VIR_BUFFER_INITIALIZER; @@ -152,7 +151,7 @@ index 60962ee7c1..4a4cff434b 100644 if (vsock->model) { virBufferAsprintf(&attrBuf, " model='%s'", -@@ -28427,6 +28451,9 @@ virDomainVsockDefFormat(virBufferPtr buf, +@@ -28381,6 +28405,9 @@ virDomainVsockDefFormat(virBufferPtr buf, if (virDomainDeviceInfoFormat(&childBuf, &vsock->info, 0) < 0) return -1; @@ -175,10 +174,10 @@ index 118077edaa..3aed1fb22a 100644 struct _virDomainVirtioOptions { diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c -index ed5f60e82e..11e59a67d2 100644 +index 67d7334b0f..998c3c90f8 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c -@@ -9799,6 +9799,10 @@ qemuBuildVsockDevStr(virDomainDefPtr def, +@@ -9965,6 +9965,10 @@ qemuBuildVsockDevStr(virDomainDefPtr def, virBufferAsprintf(&buf, ",id=%s", vsock->info.alias); virBufferAsprintf(&buf, ",guest-cid=%u", vsock->guest_cid); virBufferAsprintf(&buf, ",vhostfd=%s%u", fdprefix, priv->vhostfd); @@ -276,10 +275,10 @@ index 0000000000..dbfe082a6f + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c -index ff92af606d..66df797ef2 100644 +index 629f5ac100..a22e3ba157 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c -@@ -3054,6 +3054,7 @@ mymain(void) +@@ -3056,6 +3056,7 @@ mymain(void) DO_TEST_CAPS_LATEST("vhost-vsock-auto"); DO_TEST_CAPS_ARCH_LATEST("vhost-vsock-ccw", "s390x"); DO_TEST_CAPS_ARCH_LATEST("vhost-vsock-ccw-auto", "s390x"); @@ -296,10 +295,10 @@ index 0000000000..78971a8ef9 +../qemuxml2argvdata/vhost-vsock-ccw-iommu.xml \ No newline at end of file diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c -index c8218e423e..0e0097da1b 100644 +index 60efcac6c8..461b5bc68f 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c -@@ -1429,6 +1429,8 @@ mymain(void) +@@ -1433,6 +1433,8 @@ mymain(void) QEMU_CAPS_CCW); DO_TEST("vhost-vsock-ccw-auto", QEMU_CAPS_DEVICE_VHOST_VSOCK, QEMU_CAPS_CCW); @@ -309,5 +308,5 @@ index c8218e423e..0e0097da1b 100644 DO_TEST_CAPS_LATEST("vhost-user-fs-fd-memory"); DO_TEST_CAPS_LATEST("vhost-user-fs-hugepages"); -- -2.31.0 +2.30.0 diff --git a/SOURCES/libvirt-qemu-Build-HMAT-command-line.patch b/SOURCES/libvirt-qemu-Build-HMAT-command-line.patch new file mode 100644 index 0000000..d65e257 --- /dev/null +++ b/SOURCES/libvirt-qemu-Build-HMAT-command-line.patch @@ -0,0 +1,388 @@ +From fe08906feb3ab006c4013957895cfb4fa69b7396 Mon Sep 17 00:00:00 2001 +Message-Id: <fe08906feb3ab006c4013957895cfb4fa69b7396@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Wed, 7 Oct 2020 18:45:43 +0200 +Subject: [PATCH] qemu: Build HMAT command line +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1786303 + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit aeecbc87b7317e88a8ef8c82b29bcacd1005c8c2) + +Apart from conflicts below, I had to remove '-cpu qemu64' from +tests/qemuxml2argvdata/numatune-hmat.x86_64-latest.args to make +qemuxml2argvtest happy. This is because +3b8feb4793cef66f5dbfb9bdabe4d40834f1e90e isn't backported. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Conflicts: +- src/qemu/qemu_command.c: Context +- src/qemu/qemu_validate.c: The file doesn't exist in downstream. +I've made the change to validator that lives in qemu_domain.c. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <0e8dfded8022b564ec7d0563cd745a0d3ffc815f.1602087923.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/conf/numa_conf.c | 7 + + src/qemu/qemu_command.c | 171 ++++++++++++++++++ + src/qemu/qemu_domain.c | 7 + + .../numatune-hmat.x86_64-latest.args | 52 ++++++ + tests/qemuxml2argvtest.c | 1 + + tests/qemuxml2xmltest.c | 2 +- + 6 files changed, 239 insertions(+), 1 deletion(-) + create mode 100644 tests/qemuxml2argvdata/numatune-hmat.x86_64-latest.args + +diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c +index 277a695d84..5a92eb35cc 100644 +--- a/src/conf/numa_conf.c ++++ b/src/conf/numa_conf.c +@@ -1875,6 +1875,13 @@ virDomainNumaGetNodeInitiator(const virDomainNuma *numa, + if (!numa || node >= numa->nmem_nodes) + return -1; + ++ /* A NUMA node which has at least one vCPU is initiator to itself by ++ * definition. */ ++ if (numa->mem_nodes[node].cpumask) ++ return node; ++ ++ /* For the rest, "NUMA node that has best performance (the lowest ++ * latency or largest bandwidth) to this NUMA node." */ + for (i = 0; i < numa->ninterconnects; i++) { + const virDomainNumaInterconnect *l = &numa->interconnects[i]; + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index ac63d18a42..959207bfea 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -7172,6 +7172,9 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, + virBufferAsprintf(&buf, ",pflash1=%s", priv->pflash1->nodeformat); + } + ++ if (virDomainNumaHasHMAT(def->numa)) ++ virBufferAddLit(&buf, ",hmat=on"); ++ + virCommandAddArgBuffer(cmd, &buf); + + return 0; +@@ -7355,6 +7358,134 @@ qemuBuildIOThreadCommandLine(virCommandPtr cmd, + } + + ++static int ++qemuBuilNumaCellCache(virCommandPtr cmd, ++ const virDomainDef *def, ++ size_t cell) ++{ ++ size_t ncaches = virDomainNumaGetNodeCacheCount(def->numa, cell); ++ size_t i; ++ ++ if (ncaches == 0) ++ return 0; ++ ++ for (i = 0; i < ncaches; i++) { ++ g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; ++ unsigned int level; ++ unsigned int size; ++ unsigned int line; ++ virDomainCacheAssociativity associativity; ++ virDomainCachePolicy policy; ++ ++ if (virDomainNumaGetNodeCache(def->numa, cell, i, ++ &level, &size, &line, ++ &associativity, &policy) < 0) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("Unable to format NUMA node cache")); ++ return -1; ++ } ++ ++ virBufferAsprintf(&buf, ++ "hmat-cache,node-id=%zu,size=%uK,level=%u", ++ cell, size, level); ++ ++ switch (associativity) { ++ case VIR_DOMAIN_CACHE_ASSOCIATIVITY_NONE: ++ virBufferAddLit(&buf, ",associativity=none"); ++ break; ++ case VIR_DOMAIN_CACHE_ASSOCIATIVITY_DIRECT: ++ virBufferAddLit(&buf, ",associativity=direct"); ++ break; ++ case VIR_DOMAIN_CACHE_ASSOCIATIVITY_FULL: ++ virBufferAddLit(&buf, ",associativity=complex"); ++ break; ++ case VIR_DOMAIN_CACHE_ASSOCIATIVITY_LAST: ++ break; ++ } ++ ++ switch (policy) { ++ case VIR_DOMAIN_CACHE_POLICY_NONE: ++ virBufferAddLit(&buf, ",policy=none"); ++ break; ++ case VIR_DOMAIN_CACHE_POLICY_WRITEBACK: ++ virBufferAddLit(&buf, ",policy=write-back"); ++ break; ++ case VIR_DOMAIN_CACHE_POLICY_WRITETHROUGH: ++ virBufferAddLit(&buf, ",policy=write-through"); ++ break; ++ case VIR_DOMAIN_CACHE_POLICY_LAST: ++ break; ++ } ++ ++ if (line > 0) ++ virBufferAsprintf(&buf, ",line=%u", line); ++ ++ virCommandAddArg(cmd, "-numa"); ++ virCommandAddArgBuffer(cmd, &buf); ++ } ++ ++ return 0; ++} ++ ++ ++VIR_ENUM_DECL(qemuDomainMemoryHierarchy); ++VIR_ENUM_IMPL(qemuDomainMemoryHierarchy, ++ 4, /* Maximum level of cache */ ++ "memory", /* Special case, whole memory not specific cache */ ++ "first-level", ++ "second-level", ++ "third-level"); ++ ++static int ++qemuBuildNumaHMATCommandLine(virCommandPtr cmd, ++ const virDomainDef *def) ++{ ++ size_t nlatencies; ++ size_t i; ++ ++ if (!def->numa) ++ return 0; ++ ++ nlatencies = virDomainNumaGetInterconnectsCount(def->numa); ++ for (i = 0; i < nlatencies; i++) { ++ g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; ++ virDomainNumaInterconnectType type; ++ unsigned int initiator; ++ unsigned int target; ++ unsigned int cache; ++ virDomainMemoryLatency accessType; ++ unsigned long value; ++ const char *hierarchyStr; ++ const char *accessStr; ++ ++ if (virDomainNumaGetInterconnect(def->numa, i, ++ &type, &initiator, &target, ++ &cache, &accessType, &value) < 0) ++ return -1; ++ ++ hierarchyStr = qemuDomainMemoryHierarchyTypeToString(cache); ++ accessStr = virDomainMemoryLatencyTypeToString(accessType); ++ virBufferAsprintf(&buf, ++ "hmat-lb,initiator=%u,target=%u,hierarchy=%s,data-type=%s-", ++ initiator, target, hierarchyStr, accessStr); ++ ++ switch (type) { ++ case VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_LATENCY: ++ virBufferAsprintf(&buf, "latency,latency=%lu", value); ++ break; ++ case VIR_DOMAIN_NUMA_INTERCONNECT_TYPE_BANDWIDTH: ++ virBufferAsprintf(&buf, "bandwidth,bandwidth=%luK", value); ++ break; ++ } ++ ++ virCommandAddArg(cmd, "-numa"); ++ virCommandAddArgBuffer(cmd, &buf); ++ } ++ ++ return 0; ++} ++ ++ + static int + qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg, + virDomainDefPtr def, +@@ -7367,13 +7498,20 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg, + char *next = NULL; + virBufferPtr nodeBackends = NULL; + bool needBackend = false; ++ bool hmat = false; + int rc; + int ret = -1; + size_t ncells = virDomainNumaGetNodeCount(def->numa); ++ ssize_t masterInitiator = -1; + + if (!virDomainNumatuneNodesetIsAvailable(def->numa, priv->autoNodeset)) + goto cleanup; + ++ if (virDomainNumaHasHMAT(def->numa)) { ++ needBackend = true; ++ hmat = true; ++ } ++ + if (VIR_ALLOC_N(nodeBackends, ncells) < 0) + goto cleanup; + +@@ -7397,8 +7535,22 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg, + qemuBuildMemPathStr(cfg, def, cmd, priv) < 0) + goto cleanup; + ++ for (i = 0; i < ncells; i++) { ++ if (virDomainNumaGetNodeCpumask(def->numa, i)) { ++ masterInitiator = i; ++ break; ++ } ++ } ++ ++ if (masterInitiator) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("At least one NUMA node has to have CPUs")); ++ goto cleanup; ++ } ++ + for (i = 0; i < ncells; i++) { + virBitmapPtr cpumask = virDomainNumaGetNodeCpumask(def->numa, i); ++ ssize_t initiator = virDomainNumaGetNodeInitiator(def->numa, i); + + if (needBackend) { + virCommandAddArg(cmd, "-object"); +@@ -7423,6 +7575,13 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg, + } + } + ++ if (hmat) { ++ if (initiator < 0) ++ initiator = masterInitiator; ++ ++ virBufferAsprintf(&buf, ",initiator=%zd", initiator); ++ } ++ + if (needBackend) + virBufferAsprintf(&buf, ",memdev=ram-node%zu", i); + else +@@ -7448,6 +7607,18 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg, + } + } + ++ if (hmat) { ++ if (qemuBuildNumaHMATCommandLine(cmd, def) < 0) ++ goto cleanup; ++ ++ /* This can't be moved into any of the loops above, ++ * because hmat-cache can be specified only after hmat-lb. */ ++ for (i = 0; i < ncells; i++) { ++ if (qemuBuilNumaCellCache(cmd, def, i) < 0) ++ goto cleanup; ++ } ++ } ++ + ret = 0; + + cleanup: +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index be25790f12..e51e176a80 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -5904,6 +5904,13 @@ qemuDomainDefValidate(const virDomainDef *def, + } + } + ++ if (virDomainNumaHasHMAT(def->numa) && ++ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_NUMA_HMAT)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", ++ _("HMAT is not supported with this QEMU")); ++ return -1; ++ } ++ + if (def->genidRequested && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMGENID)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", +diff --git a/tests/qemuxml2argvdata/numatune-hmat.x86_64-latest.args b/tests/qemuxml2argvdata/numatune-hmat.x86_64-latest.args +new file mode 100644 +index 0000000000..413d247a4d +--- /dev/null ++++ b/tests/qemuxml2argvdata/numatune-hmat.x86_64-latest.args +@@ -0,0 +1,52 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/tmp/lib/domain--1-QEMUGuest \ ++USER=test \ ++LOGNAME=test \ ++XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest/.local/share \ ++XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest/.cache \ ++XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest/.config \ ++QEMU_AUDIO_DRV=none \ ++/usr/bin/qemu-system-x86_64 \ ++-name guest=QEMUGuest,debug-threads=on \ ++-S \ ++-object secret,id=masterKey0,format=raw,\ ++file=/tmp/lib/domain--1-QEMUGuest/master-key.aes \ ++-machine pc,accel=tcg,usb=off,dump-guest-core=off,hmat=on \ ++-m 12288 \ ++-overcommit mem-lock=off \ ++-smp 12,sockets=12,cores=1,threads=1 \ ++-object memory-backend-ram,id=ram-node0,size=2147483648 \ ++-numa node,nodeid=0,cpus=0-3,initiator=0,memdev=ram-node0 \ ++-object memory-backend-ram,id=ram-node1,size=2147483648 \ ++-numa node,nodeid=1,cpus=4-7,initiator=1,memdev=ram-node1 \ ++-object memory-backend-ram,id=ram-node2,size=2147483648 \ ++-numa node,nodeid=2,cpus=8-11,initiator=2,memdev=ram-node2 \ ++-object memory-backend-ram,id=ram-node3,size=2147483648 \ ++-numa node,nodeid=3,initiator=0,memdev=ram-node3 \ ++-object memory-backend-ram,id=ram-node4,size=2147483648 \ ++-numa node,nodeid=4,initiator=0,memdev=ram-node4 \ ++-object memory-backend-ram,id=ram-node5,size=2147483648 \ ++-numa node,nodeid=5,initiator=0,memdev=ram-node5 \ ++-numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-latency,\ ++latency=5 \ ++-numa hmat-lb,initiator=0,target=0,hierarchy=first-level,\ ++data-type=access-latency,latency=10 \ ++-numa hmat-lb,initiator=0,target=0,hierarchy=memory,data-type=access-bandwidth,\ ++bandwidth=204800K \ ++-numa hmat-cache,node-id=0,size=10K,level=1,associativity=direct,\ ++policy=write-back,line=8 \ ++-uuid c7a5fdb2-cdaf-9455-926a-d65c16db1809 \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,fd=1729,server,nowait \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-boot strict=on \ ++-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \ ++-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ ++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ ++resourcecontrol=deny \ ++-msg timestamp=on +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index 49699e495d..629f5ac100 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -1813,6 +1813,7 @@ mymain(void) + + DO_TEST("numatune-distances", QEMU_CAPS_NUMA, QEMU_CAPS_NUMA_DIST); + DO_TEST("numatune-no-vcpu", NONE); ++ DO_TEST_CAPS_LATEST("numatune-hmat"); + + DO_TEST("numatune-auto-nodeset-invalid", NONE); + DO_TEST("numatune-auto-prefer", QEMU_CAPS_OBJECT_MEMORY_RAM, +diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c +index de1d720e1d..f790bbc6f1 100644 +--- a/tests/qemuxml2xmltest.c ++++ b/tests/qemuxml2xmltest.c +@@ -1106,7 +1106,7 @@ mymain(void) + DO_TEST("numatune-memnode-no-memory", QEMU_CAPS_OBJECT_MEMORY_FILE); + DO_TEST("numatune-distances", QEMU_CAPS_NUMA, QEMU_CAPS_NUMA_DIST); + DO_TEST("numatune-no-vcpu", QEMU_CAPS_NUMA); +- DO_TEST("numatune-hmat", NONE); ++ DO_TEST("numatune-hmat", QEMU_CAPS_NUMA_HMAT); + + DO_TEST("bios-nvram", NONE); + DO_TEST("bios-nvram-os-interleave", NONE); +-- +2.29.2 + diff --git a/SOURCES/libvirt-qemu-Fix-domfsinfo-for-non-PCI-device-information-from-guest-agent.patch b/SOURCES/libvirt-qemu-Fix-domfsinfo-for-non-PCI-device-information-from-guest-agent.patch new file mode 100644 index 0000000..d1f5cda --- /dev/null +++ b/SOURCES/libvirt-qemu-Fix-domfsinfo-for-non-PCI-device-information-from-guest-agent.patch @@ -0,0 +1,70 @@ +From c1605fba8512fc77f3e2e2bdbbca56e14a086893 Mon Sep 17 00:00:00 2001 +Message-Id: <c1605fba8512fc77f3e2e2bdbbca56e14a086893@dist-git> +From: Thomas Huth <thuth@redhat.com> +Date: Fri, 2 Oct 2020 12:32:11 +0200 +Subject: [PATCH] qemu: Fix domfsinfo for non-PCI device information from guest + agent +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +qemuAgentFSInfoToPublic() currently only sets the devAlias for PCI devices. +However, the QEMU guest agent could also provide the device name in the +"dev" field of the response for other devices instead (well, at least after +fixing another problem in the current QEMU guest agent...). So if creating +the devAlias from the PCI information failed, let's fall back to the name +provided by the guest agent. This helps to fix the empty "Target" fields +that occur when running "virsh domfsinfo" on s390x where CCW devices are +used for the guest instead of PCI devices. + +Also add a proper debug message here in case we completely failed to set the +device alias, since this problem here was very hard to debug: The only two +error messages that I've seen were "Unable to get filesystem information" +and "Unable to encode message payload" - which only indicates that something +went wrong in the RPC call. No debug message indicated the real problem, so +I had to learn the hard way why the RPC call failed (it apparently does not +like devAlias left to be NULL) and where the real problem comes from. + +Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> +Signed-off-by: Thomas Huth <thuth@redhat.com> +(cherry picked from commit f8333b3b0a7fdbc1f18ed501c043ac7618b86a16) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1858771 +Message-Id: <20201002103211.250169-2-thuth@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +--- + src/qemu/qemu_driver.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 0f06974a1b..80a4a43e2e 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -21996,14 +21996,17 @@ qemuAgentFSInfoToPublic(qemuAgentFSInfoPtr agent, + qemuAgentDiskInfoPtr agentdisk = agent->disks[i]; + virDomainDiskDefPtr diskDef; + +- if (!(diskDef = virDomainDiskByAddress(vmdef, +- &agentdisk->pci_controller, +- agentdisk->bus, +- agentdisk->target, +- agentdisk->unit))) +- continue; +- +- ret->devAlias[i] = g_strdup(diskDef->dst); ++ diskDef = virDomainDiskByAddress(vmdef, ++ &agentdisk->pci_controller, ++ agentdisk->bus, ++ agentdisk->target, ++ agentdisk->unit); ++ if (diskDef != NULL) ++ ret->devAlias[i] = g_strdup(diskDef->dst); ++ else if (agentdisk->devnode != NULL) ++ ret->devAlias[i] = g_strdup(agentdisk->devnode); ++ else ++ VIR_DEBUG("Missing devnode name for '%s'.", ret->mountpoint); + } + + return ret; +-- +2.28.0 + diff --git a/SOURCES/libvirt-qemu-Introduce-QEMU_CAPS_NUMA_HMAT-capability.patch b/SOURCES/libvirt-qemu-Introduce-QEMU_CAPS_NUMA_HMAT-capability.patch new file mode 100644 index 0000000..1354f7c --- /dev/null +++ b/SOURCES/libvirt-qemu-Introduce-QEMU_CAPS_NUMA_HMAT-capability.patch @@ -0,0 +1,97 @@ +From f1de31795f1010016beab3b669db821799e5a6d3 Mon Sep 17 00:00:00 2001 +Message-Id: <f1de31795f1010016beab3b669db821799e5a6d3@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Wed, 7 Oct 2020 18:45:42 +0200 +Subject: [PATCH] qemu: Introduce QEMU_CAPS_NUMA_HMAT capability +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This capability tracks whether QEMU is capable of defining HMAT +ACPI table for the guest. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit c2f15f1b1869c1732e529967d1851582409290fb) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Conflicts: +- src/qemu/qemu_capabilities.c: The set of capabilities diverged. +- src/qemu/qemu_capabilities.h: Ditto. +- tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml: Ditto. +- tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml: Ditto. +- tests/qemucapabilitiesdata/caps_5.0.0.ppc64.xml: Doesn't exist + downstream. +- tests/qemucapabilitiesdata/caps_5.0.0.riscv64.xml: Ditto. +- tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml: Ditto. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <bf15c10c27c81f8f2d5a23568e4aebd216756642.1602087923.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/qemu/qemu_capabilities.c | 2 ++ + src/qemu/qemu_capabilities.h | 1 + + tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml | 1 + + tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml | 1 + + 4 files changed, 5 insertions(+) + +diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c +index 278eaa0009..ce52c51199 100644 +--- a/src/qemu/qemu_capabilities.c ++++ b/src/qemu/qemu_capabilities.c +@@ -568,6 +568,7 @@ VIR_ENUM_IMPL(virQEMUCaps, + "storage.werror", + "pcie-root-port.hotplug", + "i8042", ++ "numa.hmat", + ); + + +@@ -1451,6 +1452,7 @@ static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = { + { "human-monitor-command/$savevm-monitor-nodes", QEMU_CAPS_SAVEVM_MONITOR_NODES }, + { "blockdev-add/arg-type/+nvme", QEMU_CAPS_DRIVE_NVME }, + { "blockdev-snapshot/$allow-write-only-overlay", QEMU_CAPS_BLOCKDEV_SNAPSHOT_ALLOW_WRITE_ONLY }, ++ { "set-numa-node/arg-type/+hmat-lb", QEMU_CAPS_NUMA_HMAT }, + }; + + typedef struct _virQEMUCapsObjectTypeProps virQEMUCapsObjectTypeProps; +diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h +index 15ebcb5077..98cac5b9dc 100644 +--- a/src/qemu/qemu_capabilities.h ++++ b/src/qemu/qemu_capabilities.h +@@ -548,6 +548,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ + QEMU_CAPS_STORAGE_WERROR, /* virtio-blk,scsi-hd.werror */ + QEMU_CAPS_PCIE_ROOT_PORT_HOTPLUG, /* pcie-root-port.hotplug */ + QEMU_CAPS_DEVICE_I8042, /* PS/2 controller */ ++ QEMU_CAPS_NUMA_HMAT, /* -numa hmat */ + + QEMU_CAPS_LAST /* this must always be the last item */ + } virQEMUCapsFlags; +diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml +index 140a466910..92da5cbd94 100644 +--- a/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml ++++ b/tests/qemucapabilitiesdata/caps_5.0.0.aarch64.xml +@@ -181,6 +181,7 @@ + <flag name='cpu.kvm-no-adjvtime'/> + <flag name='vhost-user-fs'/> + <flag name='storage.werror'/> ++ <flag name='numa.hmat'/> + <version>4002050</version> + <kvmVersion>0</kvmVersion> + <microcodeVersion>61700241</microcodeVersion> +diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml +index 733e6b1eb4..0b841a49ac 100644 +--- a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml ++++ b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml +@@ -226,6 +226,7 @@ + <flag name='storage.werror'/> + <flag name='pcie-root-port.hotplug'/> + <flag name='i8042'/> ++ <flag name='numa.hmat'/> + <version>4002091</version> + <kvmVersion>0</kvmVersion> + <microcodeVersion>43100241</microcodeVersion> +-- +2.29.2 + diff --git a/SOURCES/libvirt-qemu-agent-set-ifname-to-NULL-after-freeing.patch b/SOURCES/libvirt-qemu-agent-set-ifname-to-NULL-after-freeing.patch new file mode 100644 index 0000000..4eabc76 --- /dev/null +++ b/SOURCES/libvirt-qemu-agent-set-ifname-to-NULL-after-freeing.patch @@ -0,0 +1,42 @@ +From 1b7381da7db7092bf774779a610f153532efa5d4 Mon Sep 17 00:00:00 2001 +Message-Id: <1b7381da7db7092bf774779a610f153532efa5d4@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com> +Date: Tue, 29 Sep 2020 14:43:06 +0200 +Subject: [PATCH] qemu: agent: set ifname to NULL after freeing +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +CVE-2020-25637 + +Signed-off-by: Ján Tomko <jtomko@redhat.com> +Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> +Fixes: 0977b8aa071de550e1a013d35e2c72615e65d520 +Reviewed-by: Mauro Matteo Cascella <mcascell@redhat.com> +(cherry picked from commit a63b48c5ecef077bf0f909a85f453a605600cf05) +Signed-off-by: Ján Tomko <jtomko@redhat.com> + +Conflicts: src/qemu/qemu_agent.c + Commit ee247e1d which switched virStringListFree + to g_strfreev is missing downstream. +Message-Id: <01acbf07b5b165b89cc73a127fe7bda666bdf235.1601383236.git.jtomko@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/qemu/qemu_agent.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c +index f13126aeee..968534b594 100644 +--- a/src/qemu/qemu_agent.c ++++ b/src/qemu/qemu_agent.c +@@ -2192,6 +2192,7 @@ qemuAgentGetInterfaces(qemuAgentPtr mon, + + /* Has to be freed for each interface. */ + virStringListFree(ifname); ++ ifname = NULL; + + /* as well as IP address which - moreover - + * can be presented multiple times */ +-- +2.28.0 + diff --git a/SOURCES/libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch b/SOURCES/libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch new file mode 100644 index 0000000..8545d91 --- /dev/null +++ b/SOURCES/libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch @@ -0,0 +1,114 @@ +From 9a993a7d566b7acdc548c1f0114b99fe17ba3c12 Mon Sep 17 00:00:00 2001 +Message-Id: <9a993a7d566b7acdc548c1f0114b99fe17ba3c12@dist-git> +From: Jonathon Jongsma <jjongsma@redhat.com> +Date: Fri, 4 Dec 2020 15:02:42 -0600 +Subject: [PATCH] qemu: format 'ramfb' attribute for mediated devices +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It's possible to use ramfb as the boot display of an assigned vgpu +device. This was introduced in 4b95738c, but unfortunately the attribute +was not formatted into the xml output for such a device. This patch +fixes that oversight and adds a xml2xml test to verify proper behavior. + +https://bugzilla.redhat.com/show_bug.cgi?id=1847791 + +(the expected test results were massaged slightly due to the fact that +commit 3b8feb4793cef66f5dbfb9bdabe4d40834f1e90e is not present in this +build). + +Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +Signed-off-by: Ján Tomko <jtomko@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +(cherry picked from commit c5815b31976f3982d18c7f6c1367ab6e403eb7eb) + +https://bugzilla.redhat.com/show_bug.cgi?id=1876297 + +Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> +Message-Id: <20201204210242.822641-2-jjongsma@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +--- + src/conf/domain_conf.c | 3 ++ + ...stdev-mdev-display-ramfb.x86_64-latest.xml | 41 +++++++++++++++++++ + tests/qemuxml2xmltest.c | 1 + + 3 files changed, 45 insertions(+) + create mode 100644 tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index cd5c15f297..c5a0442c6f 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -27603,6 +27603,9 @@ virDomainHostdevDefFormat(virBufferPtr buf, + if (mdevsrc->display != VIR_TRISTATE_SWITCH_ABSENT) + virBufferAsprintf(buf, " display='%s'", + virTristateSwitchTypeToString(mdevsrc->display)); ++ if (mdevsrc->ramfb != VIR_TRISTATE_SWITCH_ABSENT) ++ virBufferAsprintf(buf, " ramfb='%s'", ++ virTristateSwitchTypeToString(mdevsrc->ramfb)); + } + + } +diff --git a/tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml b/tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml +new file mode 100644 +index 0000000000..90c49842a5 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/hostdev-mdev-display-ramfb.x86_64-latest.xml +@@ -0,0 +1,41 @@ ++<domain type='qemu'> ++ <name>QEMUGuest2</name> ++ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> ++ <memory unit='KiB'>219136</memory> ++ <currentMemory unit='KiB'>219136</currentMemory> ++ <vcpu placement='static'>1</vcpu> ++ <os> ++ <type arch='i686' machine='pc'>hvm</type> ++ <boot dev='hd'/> ++ </os> ++ <clock offset='utc'/> ++ <on_poweroff>destroy</on_poweroff> ++ <on_reboot>restart</on_reboot> ++ <on_crash>destroy</on_crash> ++ <devices> ++ <emulator>/usr/bin/qemu-system-i386</emulator> ++ <controller type='usb' index='0' model='piix3-uhci'> ++ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> ++ </controller> ++ <controller type='pci' index='0' model='pci-root'/> ++ <controller type='ide' index='0'> ++ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> ++ </controller> ++ <input type='mouse' bus='ps2'/> ++ <input type='keyboard' bus='ps2'/> ++ <graphics type='vnc' port='-1' autoport='yes'> ++ <listen type='address'/> ++ </graphics> ++ <video> ++ <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/> ++ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> ++ </video> ++ <hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci' display='on' ramfb='on'> ++ <source> ++ <address uuid='53764d0e-85a0-42b4-af5c-2046b460b1dc'/> ++ </source> ++ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> ++ </hostdev> ++ <memballoon model='none'/> ++ </devices> ++</domain> +diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c +index f790bbc6f1..60efcac6c8 100644 +--- a/tests/qemuxml2xmltest.c ++++ b/tests/qemuxml2xmltest.c +@@ -524,6 +524,7 @@ mymain(void) + QEMU_CAPS_VFIO_PCI_DISPLAY, + QEMU_CAPS_DEVICE_VFIO_PCI, + QEMU_CAPS_VNC); ++ DO_TEST_CAPS_LATEST("hostdev-mdev-display-ramfb"); + DO_TEST("pci-rom", NONE); + DO_TEST("pci-rom-disabled", NONE); + DO_TEST("pci-rom-disabled-invalid", NONE); +-- +2.29.2 + diff --git a/SOURCES/libvirt-qemu-move-cgroup-cpu-period-and-quota-defines-to-vircgroup.h.patch b/SOURCES/libvirt-qemu-move-cgroup-cpu-period-and-quota-defines-to-vircgroup.h.patch new file mode 100644 index 0000000..2ee6d62 --- /dev/null +++ b/SOURCES/libvirt-qemu-move-cgroup-cpu-period-and-quota-defines-to-vircgroup.h.patch @@ -0,0 +1,130 @@ +From 7a964b43185f4d818eec0c39197bde17371f4c2b Mon Sep 17 00:00:00 2001 +Message-Id: <7a964b43185f4d818eec0c39197bde17371f4c2b@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Thu, 21 Jan 2021 10:24:03 -0300 +Subject: [PATCH] qemu: move cgroup cpu period and quota defines to vircgroup.h + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit a818e3f6f02ffc9c1c9ea6e8131c307213fa18ec) + +Conflicts: src/qemu/qemu_driver.c + Context due to lots of changes upstream in the file. + +https://bugzilla.redhat.com/1915733 + +Signed-off-by: Daniel Henrique Barboza <dbarboza@redhat.com> +Message-Id: <20210121132406.337681-2-dbarboza@redhat.com> +Reviewed-by: Pavel Hrdina <phrdina@redhat.com> +--- + src/qemu/qemu_driver.c | 21 ++++++++------------- + src/util/vircgroup.h | 5 +++++ + 2 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 80a4a43e2e..a1103a96dd 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -122,11 +122,6 @@ VIR_LOG_INIT("qemu.qemu_driver"); + + #define QEMU_NB_NUMA_PARAM 2 + +-#define QEMU_SCHED_MIN_PERIOD 1000LL +-#define QEMU_SCHED_MAX_PERIOD 1000000LL +-#define QEMU_SCHED_MIN_QUOTA 1000LL +-#define QEMU_SCHED_MAX_QUOTA 18446744073709551LL +- + #define QEMU_GUEST_VCPU_MAX_ID 4096 + + #define QEMU_NB_BLKIO_PARAM 6 +@@ -10655,7 +10650,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, + + } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD)) { + SCHED_RANGE_CHECK(value_ul, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD, +- QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD); ++ VIR_CGROUP_CPU_PERIOD_MIN, VIR_CGROUP_CPU_PERIOD_MAX); + + if (def && value_ul) { + if ((rc = qemuSetVcpusBWLive(vm, priv->cgroup, value_ul, 0))) +@@ -10675,7 +10670,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, + + } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA)) { + SCHED_RANGE_CHECK(value_l, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA, +- QEMU_SCHED_MIN_QUOTA, QEMU_SCHED_MAX_QUOTA); ++ VIR_CGROUP_CPU_QUOTA_MIN, VIR_CGROUP_CPU_QUOTA_MAX); + + if (def && value_l) { + if ((rc = qemuSetVcpusBWLive(vm, priv->cgroup, 0, value_l))) +@@ -10695,7 +10690,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, + + } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD)) { + SCHED_RANGE_CHECK(value_ul, VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD, +- QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD); ++ VIR_CGROUP_CPU_PERIOD_MIN, VIR_CGROUP_CPU_PERIOD_MAX); + + if (def && value_ul) { + if ((rc = qemuSetGlobalBWLive(priv->cgroup, value_ul, 0))) +@@ -10715,7 +10710,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, + + } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA)) { + SCHED_RANGE_CHECK(value_l, VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA, +- QEMU_SCHED_MIN_QUOTA, QEMU_SCHED_MAX_QUOTA); ++ VIR_CGROUP_CPU_QUOTA_MIN, VIR_CGROUP_CPU_QUOTA_MAX); + + if (def && value_l) { + if ((rc = qemuSetGlobalBWLive(priv->cgroup, 0, value_l))) +@@ -10735,7 +10730,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, + + } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD)) { + SCHED_RANGE_CHECK(value_ul, VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD, +- QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD); ++ VIR_CGROUP_CPU_PERIOD_MIN, VIR_CGROUP_CPU_PERIOD_MAX); + + if (def && value_ul) { + if ((rc = qemuSetEmulatorBandwidthLive(priv->cgroup, +@@ -10756,7 +10751,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, + + } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_EMULATOR_QUOTA)) { + SCHED_RANGE_CHECK(value_l, VIR_DOMAIN_SCHEDULER_EMULATOR_QUOTA, +- QEMU_SCHED_MIN_QUOTA, QEMU_SCHED_MAX_QUOTA); ++ VIR_CGROUP_CPU_QUOTA_MIN, VIR_CGROUP_CPU_QUOTA_MAX); + + if (def && value_l) { + if ((rc = qemuSetEmulatorBandwidthLive(priv->cgroup, +@@ -10777,7 +10772,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, + + } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD)) { + SCHED_RANGE_CHECK(value_ul, VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD, +- QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD); ++ VIR_CGROUP_CPU_PERIOD_MIN, VIR_CGROUP_CPU_PERIOD_MAX); + + if (def && value_ul) { + if ((rc = qemuSetIOThreadsBWLive(vm, priv->cgroup, value_ul, 0))) +@@ -10797,7 +10792,7 @@ qemuDomainSetSchedulerParametersFlags(virDomainPtr dom, + + } else if (STREQ(param->field, VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA)) { + SCHED_RANGE_CHECK(value_l, VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA, +- QEMU_SCHED_MIN_QUOTA, QEMU_SCHED_MAX_QUOTA); ++ VIR_CGROUP_CPU_QUOTA_MIN, VIR_CGROUP_CPU_QUOTA_MAX); + + if (def && value_l) { + if ((rc = qemuSetIOThreadsBWLive(vm, priv->cgroup, 0, value_l))) +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index 3eefe78787..83fa74840f 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -243,6 +243,11 @@ virCgroupGetDomainTotalCpuStats(virCgroupPtr group, + int virCgroupSetCpuShares(virCgroupPtr group, unsigned long long shares); + int virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares); + ++#define VIR_CGROUP_CPU_PERIOD_MIN 1000LL ++#define VIR_CGROUP_CPU_PERIOD_MAX 1000000LL ++#define VIR_CGROUP_CPU_QUOTA_MIN 1000LL ++#define VIR_CGROUP_CPU_QUOTA_MAX 18446744073709551LL ++ + int virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period); + int virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period); + +-- +2.30.0 + diff --git a/SOURCES/libvirt-qemu-substitute-missing-model-name-for-host-passthrough.patch b/SOURCES/libvirt-qemu-substitute-missing-model-name-for-host-passthrough.patch new file mode 100644 index 0000000..2bb13d9 --- /dev/null +++ b/SOURCES/libvirt-qemu-substitute-missing-model-name-for-host-passthrough.patch @@ -0,0 +1,58 @@ +From 961deedc28962b55c37430f974016aced31e1120 Mon Sep 17 00:00:00 2001 +Message-Id: <961deedc28962b55c37430f974016aced31e1120@dist-git> +From: Collin Walling <walling@linux.ibm.com> +Date: Fri, 2 Oct 2020 10:13:11 +0200 +Subject: [PATCH] qemu: substitute missing model name for host-passthrough + +Before: + $ uname -m + s390x + $ cat passthrough-cpu.xml + <cpu check="none" mode="host-passthrough" /> + $ virsh hypervisor-cpu-compare passthrough-cpu.xml + error: Failed to compare hypervisor CPU with passthrough-cpu.xml + error: internal error: unable to execute QEMU command 'query-cpu-model-comp + arison': Invalid parameter type for 'modelb.name', expected: string + +After: + $ virsh hypervisor-cpu-compare passthrough-cpu.xml + CPU described in passthrough-cpu.xml is identical to the CPU provided by hy + pervisor on the host + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Signed-off-by: Collin Walling <walling@linux.ibm.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +(cherry picked from commit 9c6996124f4ef1635fbfe47090dadaf5a12b42e9) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1850680 + +Signed-off-by: Tim Wiederhake <twiederh@redhat.com> +Message-Id: <20201002081311.449901-2-twiederh@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/qemu/qemu_driver.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index b5df0c63d4..f8a259e020 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -13539,6 +13539,15 @@ qemuConnectCompareHypervisorCPU(virConnectPtr conn, + if (virCPUDefParseXMLString(xmlCPU, VIR_CPU_TYPE_AUTO, &cpu) < 0) + goto cleanup; + ++ if (!cpu->model) { ++ if (cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH) { ++ cpu->model = g_strdup("host"); ++ } else { ++ virReportError(VIR_ERR_INVALID_ARG, "%s", ++ _("cpu parameter is missing a model name")); ++ goto cleanup; ++ } ++ } + ret = qemuConnectCPUModelComparison(qemuCaps, cfg->libDir, + cfg->user, cfg->group, + hvCPU, cpu, failIncompatible); +-- +2.28.0 + diff --git a/SOURCES/libvirt-qemuBuildMachineCommandLine-Drop-needless-check.patch b/SOURCES/libvirt-qemuBuildMachineCommandLine-Drop-needless-check.patch new file mode 100644 index 0000000..a904b27 --- /dev/null +++ b/SOURCES/libvirt-qemuBuildMachineCommandLine-Drop-needless-check.patch @@ -0,0 +1,46 @@ +From 4a3d416229ddf600ff985f9a90e3feb669548690 Mon Sep 17 00:00:00 2001 +Message-Id: <4a3d416229ddf600ff985f9a90e3feb669548690@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Wed, 7 Oct 2020 18:45:36 +0200 +Subject: [PATCH] qemuBuildMachineCommandLine: Drop needless check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The machine can not be NULL at this point - +qemuDomainDefPostParse() makes sure it isn't. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit fe43b3a5a5532377f7de40e77ca9ffde5aa2ca7e) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <4a0c05b78ac65e598b919acdb66d24a19fcf6251.1602087923.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/qemu/qemu_command.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 8c4f7a015f..1a573c2817 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -6977,13 +6977,6 @@ qemuBuildMachineCommandLine(virCommandPtr cmd, + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + size_t i; + +- /* This should *never* be NULL, since we always provide +- * a machine in the capabilities data for QEMU. So this +- * check is just here as a safety in case the unexpected +- * happens */ +- if (!def->os.machine) +- return 0; +- + virCommandAddArg(cmd, "-machine"); + virBufferAdd(&buf, def->os.machine, -1); + +-- +2.29.2 + diff --git a/SOURCES/libvirt-qemuBuildNumaCommandLine-Fix-masterInitiator-check.patch b/SOURCES/libvirt-qemuBuildNumaCommandLine-Fix-masterInitiator-check.patch new file mode 100644 index 0000000..2186773 --- /dev/null +++ b/SOURCES/libvirt-qemuBuildNumaCommandLine-Fix-masterInitiator-check.patch @@ -0,0 +1,46 @@ +From a8905f41cd62a0553e703f1b653dd4f6b1acd31f Mon Sep 17 00:00:00 2001 +Message-Id: <a8905f41cd62a0553e703f1b653dd4f6b1acd31f@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Wed, 7 Oct 2020 18:45:44 +0200 +Subject: [PATCH] qemuBuildNumaCommandLine: Fix @masterInitiator check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A few commits ago, in aeecbc87b73, I've implemented command line +generation for ACPI HMAT. For this, we need to know if at least +one guest NUMA node has vCPUs. This is tracked in +@masterInitiator variable, which is initialized to -1, then we +iterate through guest NUMA nodes and break the loop if we find a +node with a vCPU. After the loop, if masterInitiator is still +negative then no NUMA node has a vCPU and we error out. But this +exact check was missing comparison for negativeness. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit ccf627c110a178afa529818474e555bca62fc165) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <d126e3fe0064d127a1ce6f36c36708e7501e4b5e.1602087923.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/qemu/qemu_command.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 959207bfea..67d7334b0f 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -7542,7 +7542,7 @@ qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg, + } + } + +- if (masterInitiator) { ++ if (masterInitiator < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("At least one NUMA node has to have CPUs")); + goto cleanup; +-- +2.29.2 + diff --git a/SOURCES/libvirt-qemuFirmwareFillDomain-Fill-NVRAM-template-on-migration-too.patch b/SOURCES/libvirt-qemuFirmwareFillDomain-Fill-NVRAM-template-on-migration-too.patch new file mode 100644 index 0000000..51fabce --- /dev/null +++ b/SOURCES/libvirt-qemuFirmwareFillDomain-Fill-NVRAM-template-on-migration-too.patch @@ -0,0 +1,69 @@ +From 1824bb0b44b47af95f50afd626776acfba91174d Mon Sep 17 00:00:00 2001 +Message-Id: <1824bb0b44b47af95f50afd626776acfba91174d@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Wed, 7 Oct 2020 13:20:04 +0200 +Subject: [PATCH] qemuFirmwareFillDomain: Fill NVRAM template on migration too + +In 8e1804f9f66 I've tried to fix the following use case: domain +is started with path to UEFI only and relies on libvirt to figure +out corresponding NVRAM template to create a per-domain copy +from. The fix consisted of having a check tailored exactly for +this use case and if it's hit then using FW autoselection to +figure it out. Unfortunately, the NVRAM template is not saved in +the inactive XML (well, the domain might be transient anyway). +Then, as a part of that check we see whether the per-domain copy +doesn't exist already and if it does then no template is looked +up hence no template will appear in the live XML. + +This works, until the domain is migrated. At the destination, the +per-domain copy will not exist so we need to know the template to +create the per-domain copy from. But we don't even get to the +check because we are not starting a fresh new domain and thus the +qemuFirmwareFillDomain() function quits early. + +The solution is to switch order of these two checks. That is +evaluate the check for the old style before checking flags. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1852910 +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Andrea Bolognani <abologna@redhat.com> +(cherry picked from commit c43622f06e295edcb9cedf33583f0bd18fb04b10) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1880418 + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <9b91110a238eba22f4b876e7b15a25d5113ee91e.1602069592.git.mprivozn@redhat.com> +Reviewed-by: Andrea Bolognani <abologna@redhat.com> +--- + src/qemu/qemu_firmware.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c +index 68e2c6b40f..c84d03f0a8 100644 +--- a/src/qemu/qemu_firmware.c ++++ b/src/qemu/qemu_firmware.c +@@ -1241,9 +1241,6 @@ qemuFirmwareFillDomain(virQEMUDriverPtr driver, + size_t i; + int ret = -1; + +- if (!(flags & VIR_QEMU_PROCESS_START_NEW)) +- return 0; +- + /* Fill in FW paths if either os.firmware is enabled, or + * loader path was provided with no nvram varstore. */ + if (def->os.firmware == VIR_DOMAIN_OS_DEF_FIRMWARE_NONE) { +@@ -1259,6 +1256,11 @@ qemuFirmwareFillDomain(virQEMUDriverPtr driver, + /* ... then we want to consult JSON FW descriptors first, + * but we don't want to fail if we haven't found a match. */ + needResult = false; ++ } else { ++ /* Domain has FW autoselection enabled => do nothing if ++ * we are not starting it from scratch. */ ++ if (!(flags & VIR_QEMU_PROCESS_START_NEW)) ++ return 0; + } + + if ((nfirmwares = qemuFirmwareFetchParsedConfigs(driver->privileged, +-- +2.28.0 + diff --git a/SOURCES/libvirt-qemu_command-Rename-qemuBuildNumaArgStr.patch b/SOURCES/libvirt-qemu_command-Rename-qemuBuildNumaArgStr.patch new file mode 100644 index 0000000..7b61648 --- /dev/null +++ b/SOURCES/libvirt-qemu_command-Rename-qemuBuildNumaArgStr.patch @@ -0,0 +1,57 @@ +From 4fd196d6126cb9daeb771522ad23ecba0e9fd5c9 Mon Sep 17 00:00:00 2001 +Message-Id: <4fd196d6126cb9daeb771522ad23ecba0e9fd5c9@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Wed, 7 Oct 2020 18:45:35 +0200 +Subject: [PATCH] qemu_command: Rename qemuBuildNumaArgStr() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The function doesn't just build the argument for -numa. Since the +-numa can be repeated multiple times, it also puts -numa onto the +cmd line. Also, the rest of the functions has 'Command' infix. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit 8ba1792785e17736db866d62b68812a9c7e7ca40) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <f5e22c8cfce2a9636303e916d97ce0501376137f.1602087923.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/qemu/qemu_command.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index ed5f60e82e..8c4f7a015f 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -7363,10 +7363,10 @@ qemuBuildIOThreadCommandLine(virCommandPtr cmd, + + + static int +-qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, +- virDomainDefPtr def, +- virCommandPtr cmd, +- qemuDomainObjPrivatePtr priv) ++qemuBuildNumaCommandLine(virQEMUDriverConfigPtr cfg, ++ virDomainDefPtr def, ++ virCommandPtr cmd, ++ qemuDomainObjPrivatePtr priv) + { + size_t i, j; + virQEMUCapsPtr qemuCaps = priv->qemuCaps; +@@ -9930,7 +9930,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver, + return NULL; + + if (virDomainNumaGetNodeCount(def->numa) && +- qemuBuildNumaArgStr(cfg, def, cmd, priv) < 0) ++ qemuBuildNumaCommandLine(cfg, def, cmd, priv) < 0) + return NULL; + + if (qemuBuildMemoryDeviceCommandLine(cmd, cfg, def, priv) < 0) +-- +2.29.2 + diff --git a/SOURCES/libvirt-qemuxml2xmltest-Add-numatune-distance-test-case.patch b/SOURCES/libvirt-qemuxml2xmltest-Add-numatune-distance-test-case.patch new file mode 100644 index 0000000..64b5e6f --- /dev/null +++ b/SOURCES/libvirt-qemuxml2xmltest-Add-numatune-distance-test-case.patch @@ -0,0 +1,145 @@ +From 6047fac5e90c96d2d79b08e0c9d32ee7f0ad52cd Mon Sep 17 00:00:00 2001 +Message-Id: <6047fac5e90c96d2d79b08e0c9d32ee7f0ad52cd@dist-git> +From: Michal Privoznik <mprivozn@redhat.com> +Date: Wed, 7 Oct 2020 18:45:32 +0200 +Subject: [PATCH] qemuxml2xmltest: Add "numatune-distance" test case +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This test case checks that expanding NUMA distance works. On +input we accept if only distance from A to B is specified. On the +output we format the B to A distance too. + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit afb1ea67769d88290499c5c6a0c34982bad6e9c9) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <6974ab2c0987840742965ea925adcc4395f72ec2.1602087923.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + .../qemuxml2xmloutdata/numatune-distances.xml | 96 +++++++++++++++++++ + tests/qemuxml2xmltest.c | 1 + + 2 files changed, 97 insertions(+) + create mode 100644 tests/qemuxml2xmloutdata/numatune-distances.xml + +diff --git a/tests/qemuxml2xmloutdata/numatune-distances.xml b/tests/qemuxml2xmloutdata/numatune-distances.xml +new file mode 100644 +index 0000000000..48f89cb015 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/numatune-distances.xml +@@ -0,0 +1,96 @@ ++<domain type='qemu'> ++ <name>QEMUGuest</name> ++ <uuid>c7a5fdb2-cdaf-9455-926a-d65c16db1809</uuid> ++ <memory unit='KiB'>8388608</memory> ++ <currentMemory unit='KiB'>8388608</currentMemory> ++ <vcpu placement='static'>12</vcpu> ++ <os> ++ <type arch='x86_64' machine='pc'>hvm</type> ++ <boot dev='hd'/> ++ </os> ++ <features> ++ <acpi/> ++ <apic/> ++ <pae/> ++ </features> ++ <cpu> ++ <numa> ++ <cell id='0' cpus='0,11' memory='2097152' unit='KiB'> ++ <distances> ++ <sibling id='0' value='10'/> ++ <sibling id='1' value='21'/> ++ <sibling id='2' value='31'/> ++ <sibling id='3' value='41'/> ++ <sibling id='4' value='51'/> ++ <sibling id='5' value='61'/> ++ </distances> ++ </cell> ++ <cell id='1' cpus='1,10' memory='2097152' unit='KiB'> ++ <distances> ++ <sibling id='0' value='21'/> ++ <sibling id='1' value='10'/> ++ <sibling id='2' value='21'/> ++ <sibling id='3' value='31'/> ++ <sibling id='4' value='41'/> ++ <sibling id='5' value='51'/> ++ </distances> ++ </cell> ++ <cell id='2' cpus='2,9' memory='2097152' unit='KiB'> ++ <distances> ++ <sibling id='0' value='31'/> ++ <sibling id='1' value='21'/> ++ <sibling id='2' value='10'/> ++ <sibling id='3' value='21'/> ++ <sibling id='4' value='31'/> ++ <sibling id='5' value='41'/> ++ </distances> ++ </cell> ++ <cell id='3' cpus='3,8' memory='2097152' unit='KiB'> ++ <distances> ++ <sibling id='0' value='41'/> ++ <sibling id='1' value='31'/> ++ <sibling id='2' value='21'/> ++ <sibling id='3' value='10'/> ++ <sibling id='4' value='21'/> ++ <sibling id='5' value='31'/> ++ </distances> ++ </cell> ++ <cell id='4' cpus='4,7' memory='2097152' unit='KiB'> ++ <distances> ++ <sibling id='0' value='51'/> ++ <sibling id='1' value='41'/> ++ <sibling id='2' value='31'/> ++ <sibling id='3' value='21'/> ++ <sibling id='4' value='10'/> ++ <sibling id='5' value='21'/> ++ </distances> ++ </cell> ++ <cell id='5' cpus='5-6' memory='2097152' unit='KiB'> ++ <distances> ++ <sibling id='0' value='61'/> ++ <sibling id='1' value='51'/> ++ <sibling id='2' value='41'/> ++ <sibling id='3' value='31'/> ++ <sibling id='4' value='21'/> ++ <sibling id='5' value='10'/> ++ </distances> ++ </cell> ++ </numa> ++ </cpu> ++ <clock offset='utc'/> ++ <on_poweroff>destroy</on_poweroff> ++ <on_reboot>restart</on_reboot> ++ <on_crash>restart</on_crash> ++ <devices> ++ <emulator>/usr/bin/qemu-system-x86_64</emulator> ++ <controller type='usb' index='0'> ++ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> ++ </controller> ++ <controller type='pci' index='0' model='pci-root'/> ++ <input type='mouse' bus='ps2'/> ++ <input type='keyboard' bus='ps2'/> ++ <memballoon model='virtio'> ++ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> ++ </memballoon> ++ </devices> ++</domain> +diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c +index c8218e423e..6c3f5c4a9e 100644 +--- a/tests/qemuxml2xmltest.c ++++ b/tests/qemuxml2xmltest.c +@@ -1104,6 +1104,7 @@ mymain(void) + DO_TEST("numatune-auto-prefer", NONE); + DO_TEST("numatune-memnode", QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_FILE); + DO_TEST("numatune-memnode-no-memory", QEMU_CAPS_OBJECT_MEMORY_FILE); ++ DO_TEST("numatune-distances", QEMU_CAPS_NUMA, QEMU_CAPS_NUMA_DIST); + + DO_TEST("bios-nvram", NONE); + DO_TEST("bios-nvram-os-interleave", NONE); +-- +2.29.2 + diff --git a/SOURCES/libvirt-rpc-add-support-for-filtering-acls-by-uint-params.patch b/SOURCES/libvirt-rpc-add-support-for-filtering-acls-by-uint-params.patch new file mode 100644 index 0000000..78f2dcc --- /dev/null +++ b/SOURCES/libvirt-rpc-add-support-for-filtering-acls-by-uint-params.patch @@ -0,0 +1,104 @@ +From ea90c1e23120e8bde86d22d83d179bc393bc2daa Mon Sep 17 00:00:00 2001 +Message-Id: <ea90c1e23120e8bde86d22d83d179bc393bc2daa@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com> +Date: Tue, 29 Sep 2020 14:43:04 +0200 +Subject: [PATCH] rpc: add support for filtering @acls by uint params +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +CVE-2020-25637 + +Add a new field to @acl annotations for filtering by +unsigned int parameters. + +Signed-off-by: Ján Tomko <jtomko@redhat.com> +(cherry picked from commit 50864dcda191eb35732dbd80fb6ca251a6bba923) +Signed-off-by: Ján Tomko <jtomko@redhat.com> +Message-Id: <7900a5f9e8479789a5cc427a85f385095e517e87.1601383236.git.jtomko@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/remote/remote_protocol.x | 3 +++ + src/rpc/gendispatch.pl | 21 ++++++++++++++++++++- + 2 files changed, 23 insertions(+), 1 deletion(-) + +diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x +index 79cdb13a90..2527a78142 100644 +--- a/src/remote/remote_protocol.x ++++ b/src/remote/remote_protocol.x +@@ -3805,6 +3805,7 @@ enum remote_procedure { + * + * - @acl: <object>:<permission> + * - @acl: <object>:<permission>:<flagname> ++ * - @acl: <object>:<permission>::<param>:<value> + * + * Declare the access control requirements for the API. May be repeated + * multiple times, if multiple rules are required. +@@ -3814,6 +3815,8 @@ enum remote_procedure { + * <permission> is one of the permissions in access/viraccessperm.h + * <flagname> indicates the rule only applies if the named flag + * is set in the API call ++ * <param> and <value> can be used to check an unsigned int parameter ++ * against value + * + * - @aclfilter: <object>:<permission> + * +diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl +index 4cb9701e59..6a4f8074ad 100755 +--- a/src/rpc/gendispatch.pl ++++ b/src/rpc/gendispatch.pl +@@ -2104,10 +2104,12 @@ elsif ($mode eq "client") { + my @acl; + foreach (@{$acl}) { + my @bits = split /:/; +- push @acl, { object => $bits[0], perm => $bits[1], flags => $bits[2] } ++ push @acl, { object => $bits[0], perm => $bits[1], flags => $bits[2], ++ param => $bits[3], value => $bits[4] } + } + + my $checkflags = 0; ++ my $paramtocheck = undef; + for (my $i = 1 ; $i <= $#acl ; $i++) { + if ($acl[$i]->{object} ne $acl[0]->{object}) { + die "acl for '$call->{ProcName}' cannot check different objects"; +@@ -2115,6 +2117,9 @@ elsif ($mode eq "client") { + if (defined $acl[$i]->{flags} && length $acl[$i]->{flags}) { + $checkflags = 1; + } ++ if (defined $acl[$i]->{param}) { ++ $paramtocheck = $acl[$i]->{param}; ++ } + } + + my $apiname = $prefix . $call->{ProcName}; +@@ -2150,6 +2155,9 @@ elsif ($mode eq "client") { + if ($checkflags) { + push @argdecls, "unsigned int flags"; + } ++ if (defined $paramtocheck) { ++ push @argdecls, "unsigned int " . $paramtocheck; ++ } + + my $ret; + my $pass; +@@ -2210,6 +2218,17 @@ elsif ($mode eq "client") { + } + print " "; + } ++ if (defined $acl->{param}) { ++ my $param = $acl->{param}; ++ my $value = $acl->{value}; ++ if ($value =~ /^\!/) { ++ $value = substr $value, 1; ++ print "($param != ($value)) &&\n"; ++ } else { ++ print "($param == ($value)) &&\n"; ++ } ++ print " "; ++ } + print "(rv = $method(" . join(", ", @argvars, $perm) . ")) <= 0) {\n"; + print " virObjectUnref(mgr);\n"; + if ($action eq "Ensure") { +-- +2.28.0 + diff --git a/SOURCES/libvirt-rpc-gendispatch-handle-empty-flags.patch b/SOURCES/libvirt-rpc-gendispatch-handle-empty-flags.patch new file mode 100644 index 0000000..f279dc2 --- /dev/null +++ b/SOURCES/libvirt-rpc-gendispatch-handle-empty-flags.patch @@ -0,0 +1,51 @@ +From fa5b4100c32d3125eeb0d6b0024892af86ecddb0 Mon Sep 17 00:00:00 2001 +Message-Id: <fa5b4100c32d3125eeb0d6b0024892af86ecddb0@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com> +Date: Tue, 29 Sep 2020 14:43:03 +0200 +Subject: [PATCH] rpc: gendispatch: handle empty flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +CVE-2020-25637 + +Prepare for omission of the <flagname> in remote_protocol.x +@acl annotations: + @acl: <object>:<permission>:<flagname> +so that we can add more fields after, e.g.: + @acl: <object>:<permission>::<field> + +Signed-off-by: Ján Tomko <jtomko@redhat.com> +(cherry picked from commit 955029bd0ad7ef96000f529ac38204a8f4a96401) +Signed-off-by: Ján Tomko <jtomko@redhat.com> +Message-Id: <5fda9fc6cfe45eace10b8c2565a8b0c46b51f46c.1601383236.git.jtomko@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/rpc/gendispatch.pl | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl +index 8656c8f205..4cb9701e59 100755 +--- a/src/rpc/gendispatch.pl ++++ b/src/rpc/gendispatch.pl +@@ -2112,7 +2112,7 @@ elsif ($mode eq "client") { + if ($acl[$i]->{object} ne $acl[0]->{object}) { + die "acl for '$call->{ProcName}' cannot check different objects"; + } +- if (defined $acl[$i]->{flags}) { ++ if (defined $acl[$i]->{flags} && length $acl[$i]->{flags}) { + $checkflags = 1; + } + } +@@ -2200,7 +2200,7 @@ elsif ($mode eq "client") { + my $method = "virAccessManagerCheck" . $object; + my $space = ' ' x length($method); + print " if ("; +- if (defined $acl->{flags}) { ++ if (defined $acl->{flags} && length $acl->{flags}) { + my $flags = $acl->{flags}; + if ($flags =~ /^\!/) { + $flags = substr $flags, 1; +-- +2.28.0 + diff --git a/SOURCES/libvirt-rpc-require-write-acl-for-guest-agent-in-virDomainInterfaceAddresses.patch b/SOURCES/libvirt-rpc-require-write-acl-for-guest-agent-in-virDomainInterfaceAddresses.patch new file mode 100644 index 0000000..fdc0d5e --- /dev/null +++ b/SOURCES/libvirt-rpc-require-write-acl-for-guest-agent-in-virDomainInterfaceAddresses.patch @@ -0,0 +1,72 @@ +From 48f74599ffc86aa632ee39aff1aa8459880ec283 Mon Sep 17 00:00:00 2001 +Message-Id: <48f74599ffc86aa632ee39aff1aa8459880ec283@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com> +Date: Tue, 29 Sep 2020 14:43:05 +0200 +Subject: [PATCH] rpc: require write acl for guest agent in + virDomainInterfaceAddresses +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +CVE-2020-25637 + +Add a requirement for domain:write if source is set to +VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT. + +Signed-off-by: Ján Tomko <jtomko@redhat.com> +Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> +(cherry picked from commit e4116eaa44cb366b59f7fe98f4b88d04c04970ad) +Signed-off-by: Ján Tomko <jtomko@redhat.com> + +Conflicts: src/lxc/lxc_driver.c + The LXC implementation of the API was introduced + in libvirt 6.1.0, so it's not present downstream. +Message-Id: <5fdc2ebf7621698c8136b354922c687fc09286de.1601383236.git.jtomko@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/libxl/libxl_driver.c | 2 +- + src/qemu/qemu_driver.c | 2 +- + src/remote/remote_protocol.x | 1 + + 3 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c +index f021ec9c5d..1449795494 100644 +--- a/src/libxl/libxl_driver.c ++++ b/src/libxl/libxl_driver.c +@@ -6318,7 +6318,7 @@ libxlDomainInterfaceAddresses(virDomainPtr dom, + if (!(vm = libxlDomObjFromDomain(dom))) + goto cleanup; + +- if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def) < 0) ++ if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def, source) < 0) + goto cleanup; + + if (virDomainObjCheckActive(vm) < 0) +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index f8a259e020..0f06974a1b 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -22240,7 +22240,7 @@ qemuDomainInterfaceAddresses(virDomainPtr dom, + if (!(vm = qemuDomainObjFromDomain(dom))) + goto cleanup; + +- if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def) < 0) ++ if (virDomainInterfaceAddressesEnsureACL(dom->conn, vm->def, source) < 0) + goto cleanup; + + if (virDomainObjCheckActive(vm) < 0) +diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x +index 2527a78142..fbd30085b2 100644 +--- a/src/remote/remote_protocol.x ++++ b/src/remote/remote_protocol.x +@@ -6211,6 +6211,7 @@ enum remote_procedure { + /** + * @generate: none + * @acl: domain:read ++ * @acl: domain:write::source:VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT + */ + REMOTE_PROC_DOMAIN_INTERFACE_ADDRESSES = 353, + +-- +2.28.0 + diff --git a/SOURCES/libvirt-tests-add-cgroup-nested-tests.patch b/SOURCES/libvirt-tests-add-cgroup-nested-tests.patch new file mode 100644 index 0000000..300ab47 --- /dev/null +++ b/SOURCES/libvirt-tests-add-cgroup-nested-tests.patch @@ -0,0 +1,226 @@ +From c94691d796682d951ffa8fb3a4fcb985aae17d9b Mon Sep 17 00:00:00 2001 +Message-Id: <c94691d796682d951ffa8fb3a4fcb985aae17d9b@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Fri, 19 Feb 2021 13:34:00 +0100 +Subject: [PATCH] tests: add cgroup nested tests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit 85099c339346e41f457234e8ad831841aef1d5e3) + +Conflicts: + tests/vircgrouptest.c + - missing upstream g_autofree rewrite + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <abf8f7673bd59c6e3d9b596cf9a86029b1f1e9c1.1613737828.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + tests/vircgroupdata/systemd-legacy.cgroups | 12 +++ + tests/vircgroupdata/systemd-legacy.mounts | 11 +++ + .../vircgroupdata/systemd-legacy.self.cgroup | 11 +++ + tests/vircgroupdata/systemd-unified.cgroups | 13 +++ + tests/vircgroupdata/systemd-unified.mounts | 1 + + .../vircgroupdata/systemd-unified.self.cgroup | 1 + + tests/vircgrouptest.c | 82 +++++++++++++++++++ + 7 files changed, 131 insertions(+) + create mode 100644 tests/vircgroupdata/systemd-legacy.cgroups + create mode 100644 tests/vircgroupdata/systemd-legacy.mounts + create mode 100644 tests/vircgroupdata/systemd-legacy.self.cgroup + create mode 100644 tests/vircgroupdata/systemd-unified.cgroups + create mode 100644 tests/vircgroupdata/systemd-unified.mounts + create mode 100644 tests/vircgroupdata/systemd-unified.self.cgroup + +diff --git a/tests/vircgroupdata/systemd-legacy.cgroups b/tests/vircgroupdata/systemd-legacy.cgroups +new file mode 100644 +index 0000000000..444354e3c8 +--- /dev/null ++++ b/tests/vircgroupdata/systemd-legacy.cgroups +@@ -0,0 +1,12 @@ ++#subsys_name hierarchy num_cgroups enabled ++blkio 1 1 1 ++cpu 2 1 1 ++cpuacct 3 1 1 ++cpuset 4 1 1 ++devices 5 1 1 ++freezer 6 1 1 ++hugetlb 7 1 1 ++memory 8 1 1 ++net_cls 9 1 1 ++perf_event 10 1 1 ++pids 11 1 1 +diff --git a/tests/vircgroupdata/systemd-legacy.mounts b/tests/vircgroupdata/systemd-legacy.mounts +new file mode 100644 +index 0000000000..23462e9e68 +--- /dev/null ++++ b/tests/vircgroupdata/systemd-legacy.mounts +@@ -0,0 +1,11 @@ ++cgroup /not/really/sys/fs/cgroup/blkio cgroup rw,seclabel,nosuid,nodev,noexec,relatime,blkio 0 0 ++cgroup /not/really/sys/fs/cgroup/cpu cgroup rw,seclabel,nosuid,nodev,noexec,relatime,cpu 0 0 ++cgroup /not/really/sys/fs/cgroup/cpuacct cgroup rw,seclabel,nosuid,nodev,noexec,relatime,cpuacct 0 0 ++cgroup /not/really/sys/fs/cgroup/cpuset cgroup rw,seclabel,nosuid,nodev,noexec,relatime,cpuset 0 0 ++cgroup /not/really/sys/fs/cgroup/devices cgroup rw,seclabel,nosuid,nodev,noexec,relatime,devices 0 0 ++cgroup /not/really/sys/fs/cgroup/freezer cgroup rw,seclabel,nosuid,nodev,noexec,relatime,freezer 0 0 ++cgroup /not/really/sys/fs/cgroup/hugetlb cgroup rw,seclabel,nosuid,nodev,noexec,relatime,hugetlb 0 0 ++cgroup /not/really/sys/fs/cgroup/memory cgroup rw,seclabel,nosuid,nodev,noexec,relatime,memory 0 0 ++cgroup /not/really/sys/fs/cgroup/net_cls cgroup rw,seclabel,nosuid,nodev,noexec,relatime,net_cls 0 0 ++cgroup /not/really/sys/fs/cgroup/perf_event cgroup rw,seclabel,nosuid,nodev,noexec,relatime,perf_event 0 0 ++cgroup /not/really/sys/fs/cgroup/pids cgroup rw,seclabel,nosuid,nodev,noexec,relatime,pids 0 0 +diff --git a/tests/vircgroupdata/systemd-legacy.self.cgroup b/tests/vircgroupdata/systemd-legacy.self.cgroup +new file mode 100644 +index 0000000000..5c133a3c08 +--- /dev/null ++++ b/tests/vircgroupdata/systemd-legacy.self.cgroup +@@ -0,0 +1,11 @@ ++1:blkio:/libvirt ++2:cpu:/libvirt/emulator ++3:cpuacct:/libvirt/emulator ++4:cpuset:/libvirt/emulator ++5:devices:/libvirt ++6:freezer:/libvirt ++7:hugetlb:/ ++8:memory:/libvirt ++9:net_cls:/libvirt ++10:perf_event:/libvirt ++11:pids:/ +diff --git a/tests/vircgroupdata/systemd-unified.cgroups b/tests/vircgroupdata/systemd-unified.cgroups +new file mode 100644 +index 0000000000..e0d8a3561c +--- /dev/null ++++ b/tests/vircgroupdata/systemd-unified.cgroups +@@ -0,0 +1,13 @@ ++#subsys_name hierarchy num_cgroups enabled ++cpuset 0 1 1 ++cpu 0 1 1 ++cpuacct 0 1 1 ++blkio 0 1 1 ++memory 0 1 1 ++devices 0 1 1 ++freezer 0 1 1 ++net_cls 0 1 1 ++perf_event 0 1 1 ++net_prio 0 1 1 ++hugetlb 0 1 1 ++pids 0 1 1 +diff --git a/tests/vircgroupdata/systemd-unified.mounts b/tests/vircgroupdata/systemd-unified.mounts +new file mode 100644 +index 0000000000..8225f37f45 +--- /dev/null ++++ b/tests/vircgroupdata/systemd-unified.mounts +@@ -0,0 +1 @@ ++cgroup2 /not/really/sys/fs/cgroup cgroup2 rw,seclabel,nosuid,nodev,noexec,relatime,nsdelegate 0 0 +diff --git a/tests/vircgroupdata/systemd-unified.self.cgroup b/tests/vircgroupdata/systemd-unified.self.cgroup +new file mode 100644 +index 0000000000..6007ce7e18 +--- /dev/null ++++ b/tests/vircgroupdata/systemd-unified.self.cgroup +@@ -0,0 +1 @@ ++0::/libvirt/emulator +diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c +index 2d6f52fb6e..aebb90c16c 100644 +--- a/tests/vircgrouptest.c ++++ b/tests/vircgrouptest.c +@@ -636,6 +636,74 @@ static int testCgroupNewForSelfHybrid(const void *args G_GNUC_UNUSED) + } + + ++static int testCgroupNewForSelfSystemdLegacy(const void *args G_GNUC_UNUSED) ++{ ++ virCgroupPtr cgroup = NULL; ++ int ret = -1; ++ const char *empty[VIR_CGROUP_CONTROLLER_LAST] = { 0 }; ++ const char *mounts[VIR_CGROUP_CONTROLLER_LAST] = { ++ [VIR_CGROUP_CONTROLLER_BLKIO] = "/not/really/sys/fs/cgroup/blkio", ++ [VIR_CGROUP_CONTROLLER_CPU] = "/not/really/sys/fs/cgroup/cpu", ++ [VIR_CGROUP_CONTROLLER_CPUACCT] = "/not/really/sys/fs/cgroup/cpuacct", ++ [VIR_CGROUP_CONTROLLER_CPUSET] = "/not/really/sys/fs/cgroup/cpuset", ++ [VIR_CGROUP_CONTROLLER_DEVICES] = "/not/really/sys/fs/cgroup/devices", ++ [VIR_CGROUP_CONTROLLER_FREEZER] = "/not/really/sys/fs/cgroup/freezer", ++ [VIR_CGROUP_CONTROLLER_MEMORY] = "/not/really/sys/fs/cgroup/memory", ++ [VIR_CGROUP_CONTROLLER_NET_CLS] = "/not/really/sys/fs/cgroup/net_cls", ++ [VIR_CGROUP_CONTROLLER_PERF_EVENT] = "/not/really/sys/fs/cgroup/perf_event", ++ }; ++ const char *placement[VIR_CGROUP_CONTROLLER_LAST] = { ++ [VIR_CGROUP_CONTROLLER_BLKIO] = "", ++ [VIR_CGROUP_CONTROLLER_CPU] = "", ++ [VIR_CGROUP_CONTROLLER_CPUACCT] = "", ++ [VIR_CGROUP_CONTROLLER_CPUSET] = "", ++ [VIR_CGROUP_CONTROLLER_DEVICES] = "", ++ [VIR_CGROUP_CONTROLLER_FREEZER] = "", ++ [VIR_CGROUP_CONTROLLER_MEMORY] = "", ++ [VIR_CGROUP_CONTROLLER_NET_CLS] = "", ++ [VIR_CGROUP_CONTROLLER_PERF_EVENT] = "", ++ }; ++ ++ if (virCgroupNewSelf(&cgroup) < 0) { ++ fprintf(stderr, "Cannot create cgroup for self\n"); ++ goto cleanup; ++ } ++ ++ ret = validateCgroup(cgroup, "", mounts, empty, placement, NULL, NULL, 0); ++ ++ cleanup: ++ virCgroupFree(&cgroup); ++ return ret; ++} ++ ++ ++static int testCgroupNewForSelfSystemdUnified(const void *args G_GNUC_UNUSED) ++{ ++ virCgroupPtr cgroup = NULL; ++ int ret = -1; ++ const char *empty[VIR_CGROUP_CONTROLLER_LAST] = { 0 }; ++ unsigned int controllers = ++ (1 << VIR_CGROUP_CONTROLLER_CPU) | ++ (1 << VIR_CGROUP_CONTROLLER_CPUACCT) | ++ (1 << VIR_CGROUP_CONTROLLER_MEMORY) | ++ (1 << VIR_CGROUP_CONTROLLER_DEVICES) | ++ (1 << VIR_CGROUP_CONTROLLER_BLKIO); ++ ++ if (virCgroupNewSelf(&cgroup) < 0) { ++ fprintf(stderr, "Cannot create cgroup for self\n"); ++ goto cleanup; ++ } ++ ++ ret = validateCgroup(cgroup, "", empty, empty, empty, ++ "/not/really/sys/fs/cgroup", "", ++ controllers); ++ ++ cleanup: ++ virCgroupFree(&cgroup); ++ return ret; ++} ++ ++ + static int testCgroupAvailable(const void *args) + { + bool got = virCgroupAvailable(); +@@ -1125,6 +1193,20 @@ mymain(void) + ret = -1; + cleanupFakeFS(fakerootdir); + ++ fakerootdir = initFakeFS("legacy", "systemd-legacy"); ++ if (virTestRun("New cgroup for self (systemd-legacy)", ++ testCgroupNewForSelfSystemdLegacy, NULL) < 0) { ++ ret = -1; ++ } ++ cleanupFakeFS(fakerootdir); ++ ++ fakerootdir = initFakeFS("unified", "systemd-unified"); ++ if (virTestRun("New cgroup for self (systemd-unified)", ++ testCgroupNewForSelfSystemdUnified, NULL) < 0) { ++ ret = -1; ++ } ++ cleanupFakeFS(fakerootdir); ++ + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + } + +-- +2.30.0 + diff --git a/SOURCES/libvirt-tests-fix-iptables-test-case-commandline-options-in-virfirewalltest.c.patch b/SOURCES/libvirt-tests-fix-iptables-test-case-commandline-options-in-virfirewalltest.c.patch new file mode 100644 index 0000000..60697f8 --- /dev/null +++ b/SOURCES/libvirt-tests-fix-iptables-test-case-commandline-options-in-virfirewalltest.c.patch @@ -0,0 +1,522 @@ +From 2439f55f8a44ae3bddde8098f3f6ea67ccfd1d9b Mon Sep 17 00:00:00 2001 +Message-Id: <2439f55f8a44ae3bddde8098f3f6ea67ccfd1d9b@dist-git> +From: Laine Stump <laine@redhat.com> +Date: Fri, 15 Jan 2021 22:51:47 -0500 +Subject: [PATCH] tests: fix iptables test case commandline options in + virfirewalltest.c + +This test was created with all the commandlines erroneously having +"--source-host", which is not a valid iptables option. The correct +name for the option is "--source". However, since the test is just +checking that the generated commandline matches what we told it to +generate (and never actually runs iptables, as that would be a "Really +Bad Idea"(tm)), the test has always succeeded. I only found it because +I made a change to the code that caused the test to incorrectly try to +run iptables during the test, and the error message I received was +"odd" (it complained about the bad option, rather than complaining +that I had insufficient privilege to run the command). + +https://bugzilla.redhat.com/1607929 + +Signed-off-by: Laine Stump <laine@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit e9693502fb63ce5ddd07d2599daddc563c422eed) +Message-Id: <20210116035151.1066734-5-laine@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + tests/virfirewalltest.c | 168 ++++++++++++++++++++-------------------- + 1 file changed, 84 insertions(+), 84 deletions(-) + +diff --git a/tests/virfirewalltest.c b/tests/virfirewalltest.c +index 1ec768d302..40e7f4f00b 100644 +--- a/tests/virfirewalltest.c ++++ b/tests/virfirewalltest.c +@@ -206,8 +206,8 @@ testFirewallSingleGroup(const void *opaque) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"; ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source '!192.168.122.1' --jump REJECT\n"; + const struct testFirewallData *data = opaque; + + fwDisabled = data->fwDisabled; +@@ -225,12 +225,12 @@ testFirewallSingleGroup(const void *opaque) + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "!192.168.122.1", ++ "--source", "!192.168.122.1", + "--jump", "REJECT", NULL); + + if (virFirewallApply(fw) < 0) +@@ -262,8 +262,8 @@ testFirewallRemoveRule(const void *opaque) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"; ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source '!192.168.122.1' --jump REJECT\n"; + const struct testFirewallData *data = opaque; + virFirewallRulePtr fwrule; + +@@ -282,17 +282,17 @@ testFirewallRemoveRule(const void *opaque) + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + fwrule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", NULL); +- virFirewallRuleAddArg(fw, fwrule, "--source-host"); ++ virFirewallRuleAddArg(fw, fwrule, "--source"); + virFirewallRemoveRule(fw, fwrule); + + fwrule = virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", NULL); +- virFirewallRuleAddArg(fw, fwrule, "--source-host"); ++ virFirewallRuleAddArg(fw, fwrule, "--source"); + virFirewallRuleAddArgFormat(fw, fwrule, "%s", "!192.168.122.1"); + virFirewallRuleAddArgList(fw, fwrule, "--jump", "REJECT", NULL); + +@@ -325,9 +325,9 @@ testFirewallManyGroups(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n" +- IPTABLES_PATH " -w -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source '!192.168.122.1' --jump REJECT\n" ++ IPTABLES_PATH " -w -A OUTPUT --source 192.168.122.1 --jump ACCEPT\n" + IPTABLES_PATH " -w -A OUTPUT --jump DROP\n"; + const struct testFirewallData *data = opaque; + +@@ -346,19 +346,19 @@ testFirewallManyGroups(const void *opaque G_GNUC_UNUSED) + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "!192.168.122.1", ++ "--source", "!192.168.122.1", + "--jump", "REJECT", NULL); + + virFirewallStartTransaction(fw, 0); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "OUTPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, +@@ -416,9 +416,9 @@ testFirewallIgnoreFailGroup(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -w -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -A OUTPUT --source 192.168.122.1 --jump ACCEPT\n" + IPTABLES_PATH " -w -A OUTPUT --jump DROP\n"; + const struct testFirewallData *data = opaque; + +@@ -439,19 +439,19 @@ testFirewallIgnoreFailGroup(const void *opaque G_GNUC_UNUSED) + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.255", ++ "--source", "192.168.122.255", + "--jump", "REJECT", NULL); + + virFirewallStartTransaction(fw, 0); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "OUTPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, +@@ -488,9 +488,9 @@ testFirewallIgnoreFailRule(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -w -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -A OUTPUT --source 192.168.122.1 --jump ACCEPT\n" + IPTABLES_PATH " -w -A OUTPUT --jump DROP\n"; + const struct testFirewallData *data = opaque; + +@@ -511,18 +511,18 @@ testFirewallIgnoreFailRule(const void *opaque G_GNUC_UNUSED) + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_IPV4, + true, NULL, NULL, + "-A", "INPUT", +- "--source-host", "192.168.122.255", ++ "--source", "192.168.122.255", + "--jump", "REJECT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "OUTPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, +@@ -559,8 +559,8 @@ testFirewallNoRollback(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n"; ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.255 --jump REJECT\n"; + const struct testFirewallData *data = opaque; + + fwDisabled = data->fwDisabled; +@@ -580,17 +580,17 @@ testFirewallNoRollback(const void *opaque G_GNUC_UNUSED) + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.255", ++ "--source", "192.168.122.255", + "--jump", "REJECT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "!192.168.122.1", ++ "--source", "!192.168.122.1", + "--jump", "REJECT", NULL); + + if (virFirewallApply(fw) == 0) { +@@ -623,11 +623,11 @@ testFirewallSingleRollback(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n"; ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -D INPUT --source 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source '!192.168.122.1' --jump REJECT\n"; + const struct testFirewallData *data = opaque; + + fwDisabled = data->fwDisabled; +@@ -647,34 +647,34 @@ testFirewallSingleRollback(const void *opaque G_GNUC_UNUSED) + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.255", ++ "--source", "192.168.122.255", + "--jump", "REJECT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "!192.168.122.1", ++ "--source", "!192.168.122.1", + "--jump", "REJECT", NULL); + + virFirewallStartRollback(fw, 0); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-D", "INPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-D", "INPUT", +- "--source-host", "192.168.122.255", ++ "--source", "192.168.122.255", + "--jump", "REJECT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-D", "INPUT", +- "--source-host", "!192.168.122.1", ++ "--source", "!192.168.122.1", + "--jump", "REJECT", NULL); + + if (virFirewallApply(fw) == 0) { +@@ -707,10 +707,10 @@ testFirewallManyRollback(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n"; ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source '!192.168.122.1' --jump REJECT\n"; + const struct testFirewallData *data = opaque; + + fwDisabled = data->fwDisabled; +@@ -730,38 +730,38 @@ testFirewallManyRollback(const void *opaque G_GNUC_UNUSED) + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + virFirewallStartRollback(fw, 0); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-D", "INPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + virFirewallStartTransaction(fw, 0); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.255", ++ "--source", "192.168.122.255", + "--jump", "REJECT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "!192.168.122.1", ++ "--source", "!192.168.122.1", + "--jump", "REJECT", NULL); + + virFirewallStartRollback(fw, 0); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-D", "INPUT", +- "--source-host", "192.168.122.255", ++ "--source", "192.168.122.255", + "--jump", "REJECT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-D", "INPUT", +- "--source-host", "!192.168.122.1", ++ "--source", "!192.168.122.1", + "--jump", "REJECT", NULL); + + if (virFirewallApply(fw) == 0) { +@@ -794,14 +794,14 @@ testFirewallChainedRollback(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.127 --jump REJECT\n" +- IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n" +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.127 --jump REJECT\n" +- IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n" +- IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n"; ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.127 --jump REJECT\n" ++ IPTABLES_PATH " -w -A INPUT --source '!192.168.122.1' --jump REJECT\n" ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source 192.168.122.127 --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source '!192.168.122.1' --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source '!192.168.122.1' --jump REJECT\n"; + const struct testFirewallData *data = opaque; + + fwDisabled = data->fwDisabled; +@@ -821,14 +821,14 @@ testFirewallChainedRollback(const void *opaque G_GNUC_UNUSED) + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + virFirewallStartRollback(fw, 0); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-D", "INPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + +@@ -836,24 +836,24 @@ testFirewallChainedRollback(const void *opaque G_GNUC_UNUSED) + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.127", ++ "--source", "192.168.122.127", + "--jump", "REJECT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "!192.168.122.1", ++ "--source", "!192.168.122.1", + "--jump", "REJECT", NULL); + + virFirewallStartRollback(fw, 0); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-D", "INPUT", +- "--source-host", "192.168.122.127", ++ "--source", "192.168.122.127", + "--jump", "REJECT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-D", "INPUT", +- "--source-host", "!192.168.122.1", ++ "--source", "!192.168.122.1", + "--jump", "REJECT", NULL); + + +@@ -861,24 +861,24 @@ testFirewallChainedRollback(const void *opaque G_GNUC_UNUSED) + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.255", ++ "--source", "192.168.122.255", + "--jump", "REJECT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "!192.168.122.1", ++ "--source", "!192.168.122.1", + "--jump", "REJECT", NULL); + + virFirewallStartRollback(fw, VIR_FIREWALL_ROLLBACK_INHERIT_PREVIOUS); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-D", "INPUT", +- "--source-host", "192.168.122.255", ++ "--source", "192.168.122.255", + "--jump", "REJECT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-D", "INPUT", +- "--source-host", "!192.168.122.1", ++ "--source", "!192.168.122.1", + "--jump", "REJECT", NULL); + + if (virFirewallApply(fw) == 0) { +@@ -962,7 +962,7 @@ testFirewallQueryCallback(virFirewallPtr fw, + size_t i; + virFirewallAddRule(fw, layer, + "-A", "INPUT", +- "--source-host", "!192.168.122.129", ++ "--source", "!192.168.122.129", + "--jump", "REJECT", NULL); + + for (i = 0; lines[i] != NULL; i++) { +@@ -990,15 +990,15 @@ testFirewallQuery(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.127 --jump REJECT\n" ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.127 --jump REJECT\n" + IPTABLES_PATH " -w -L\n" + IPTABLES_PATH " -w -t nat -L\n" +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.130 --jump REJECT\n" +- IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.129' --jump REJECT\n" +- IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.129' --jump REJECT\n" +- IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.128 --jump REJECT\n" +- IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"; ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.130 --jump REJECT\n" ++ IPTABLES_PATH " -w -A INPUT --source '!192.168.122.129' --jump REJECT\n" ++ IPTABLES_PATH " -w -A INPUT --source '!192.168.122.129' --jump REJECT\n" ++ IPTABLES_PATH " -w -A INPUT --source 192.168.122.128 --jump REJECT\n" ++ IPTABLES_PATH " -w -A INPUT --source '!192.168.122.1' --jump REJECT\n"; + const struct testFirewallData *data = opaque; + + expectedLineNum = 0; +@@ -1020,14 +1020,14 @@ testFirewallQuery(const void *opaque G_GNUC_UNUSED) + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.1", ++ "--source", "192.168.122.1", + "--jump", "ACCEPT", NULL); + + virFirewallStartTransaction(fw, 0); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.127", ++ "--source", "192.168.122.127", + "--jump", "REJECT", NULL); + + virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_IPV4, +@@ -1043,7 +1043,7 @@ testFirewallQuery(const void *opaque G_GNUC_UNUSED) + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.130", ++ "--source", "192.168.122.130", + "--jump", "REJECT", NULL); + + +@@ -1051,12 +1051,12 @@ testFirewallQuery(const void *opaque G_GNUC_UNUSED) + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "192.168.122.128", ++ "--source", "192.168.122.128", + "--jump", "REJECT", NULL); + + virFirewallAddRule(fw, VIR_FIREWALL_LAYER_IPV4, + "-A", "INPUT", +- "--source-host", "!192.168.122.1", ++ "--source", "!192.168.122.1", + "--jump", "REJECT", NULL); + + if (virFirewallApply(fw) < 0) +-- +2.30.0 + diff --git a/SOURCES/libvirt-tests-qemuxml2argv-Use-existing-machine-type-for-numatune-distances-case.patch b/SOURCES/libvirt-tests-qemuxml2argv-Use-existing-machine-type-for-numatune-distances-case.patch new file mode 100644 index 0000000..6d94707 --- /dev/null +++ b/SOURCES/libvirt-tests-qemuxml2argv-Use-existing-machine-type-for-numatune-distances-case.patch @@ -0,0 +1,59 @@ +From 5fad3414910beac08371233414939433644a92e8 Mon Sep 17 00:00:00 2001 +Message-Id: <5fad3414910beac08371233414939433644a92e8@dist-git> +From: Peter Krempa <pkrempa@redhat.com> +Date: Wed, 7 Oct 2020 18:45:31 +0200 +Subject: [PATCH] tests: qemuxml2argv: Use existing machine type for + 'numatune-distances' case +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Peter Krempa <pkrempa@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit 99dcdf505e0856a5ebfb31f0047a1e24ec60b557) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1749518 + +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Message-Id: <4af6d896e777397acd8b5945da6bf6bf071f2e98.1602087923.git.mprivozn@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + tests/qemuxml2argvdata/numatune-distances.args | 4 ++-- + tests/qemuxml2argvdata/numatune-distances.xml | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tests/qemuxml2argvdata/numatune-distances.args b/tests/qemuxml2argvdata/numatune-distances.args +index 895efeab15..a20b40b5c5 100644 +--- a/tests/qemuxml2argvdata/numatune-distances.args ++++ b/tests/qemuxml2argvdata/numatune-distances.args +@@ -10,7 +10,7 @@ QEMU_AUDIO_DRV=none \ + /usr/bin/qemu-system-x86_64 \ + -name QEMUGuest \ + -S \ +--machine xenfv,accel=tcg,usb=off,dump-guest-core=off \ ++-machine pc,accel=tcg,usb=off,dump-guest-core=off \ + -m 12288 \ + -realtime mlock=off \ + -smp 12,sockets=12,cores=1,threads=1 \ +@@ -66,4 +66,4 @@ server,nowait \ + -rtc base=utc \ + -no-shutdown \ + -usb \ +--device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 ++-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 +diff --git a/tests/qemuxml2argvdata/numatune-distances.xml b/tests/qemuxml2argvdata/numatune-distances.xml +index 0f33526b46..fa4de6aaf6 100644 +--- a/tests/qemuxml2argvdata/numatune-distances.xml ++++ b/tests/qemuxml2argvdata/numatune-distances.xml +@@ -5,7 +5,7 @@ + <currentMemory unit='KiB'>8388608</currentMemory> + <vcpu placement='static'>12</vcpu> + <os> +- <type arch='x86_64' machine='xenfv'>hvm</type> ++ <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <features> +-- +2.29.2 + diff --git a/SOURCES/libvirt-udevProcessCSS-Check-if-def-driver-is-non-NULL.patch b/SOURCES/libvirt-udevProcessCSS-Check-if-def-driver-is-non-NULL.patch new file mode 100644 index 0000000..82ec9ba --- /dev/null +++ b/SOURCES/libvirt-udevProcessCSS-Check-if-def-driver-is-non-NULL.patch @@ -0,0 +1,69 @@ +From 32957eca8129f926d205310ee7efbc1168e8ebdc Mon Sep 17 00:00:00 2001 +Message-Id: <32957eca8129f926d205310ee7efbc1168e8ebdc@dist-git> +From: Marc Hartmayer <mhartmay@linux.ibm.com> +Date: Thu, 8 Oct 2020 11:07:00 -0400 +Subject: [PATCH] udevProcessCSS: Check if def->driver is non-NULL + +Don't process subchannel devices where `def->driver` is not set. This +fixes the following segfault: + +Thread 21 "nodedev-init" received signal SIGSEGV, Segmentation fault. +[Switching to Thread 0x3ffb08fc910 (LWP 64303)] +(gdb) bt + #0 0x000003fffd1272b4 in __strcmp_vx () at /lib64/libc.so.6 + #1 0x000003ffc260c3a8 in udevProcessCSS (device=0x3ff9018d130, def=0x3ff90194a90) + #2 0x000003ffc260cb78 in udevGetDeviceDetails (device=0x3ff9018d130, def=0x3ff90194a90) + #3 0x000003ffc260d126 in udevAddOneDevice (device=0x3ff9018d130) + #4 0x000003ffc260d414 in udevProcessDeviceListEntry (udev=0x3ffa810d800, list_entry=0x3ff90001990) + #5 0x000003ffc260d638 in udevEnumerateDevices (udev=0x3ffa810d800) + #6 0x000003ffc260e08e in nodeStateInitializeEnumerate (opaque=0x3ffa810d800) + #7 0x000003fffdaa14b6 in virThreadHelper (data=0x3ffa810df00) + #8 0x000003fffc309ed6 in start_thread () + #9 0x000003fffd185e66 in thread_start () +(gdb) p *def +$2 = { + name = 0x0, + sysfs_path = 0x3ff90198e80 "/sys/devices/css0/0.0.ff40", + parent = 0x0, + parent_sysfs_path = 0x0, + parent_wwnn = 0x0, + parent_wwpn = 0x0, + parent_fabric_wwn = 0x0, + driver = 0x0, + devnode = 0x0, + devlinks = 0x3ff90194670, + caps = 0x3ff90194380 +} + +Fixes: 05e6cdafa6e0 ("node_device: detect CSS devices") +Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com> +Reviewed-by: Erik Skultety <eskultet@redhat.com> +Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com> +(cherry picked from commit cb09344a2cccc0cc9bcefa3cb53d7af45ba92631) +https://bugzilla.redhat.com/show_bug.cgi?id=1853289 +https://bugzilla.redhat.com/show_bug.cgi?id=1865932 +Message-Id: <20201008150700.52157-6-bfiuczyn@redhat.com> +Reviewed-by: Erik Skultety <eskultet@redhat.com> +--- + src/node_device/node_device_udev.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c +index b6b28bc35a..88cf1edf50 100644 +--- a/src/node_device/node_device_udev.c ++++ b/src/node_device/node_device_udev.c +@@ -1130,8 +1130,9 @@ udevProcessCSS(struct udev_device *device, + virNodeDeviceDefPtr def) + { + /* only process IO subchannel and vfio-ccw devices to keep the list sane */ +- if (STRNEQ(def->driver, "io_subchannel") && +- STRNEQ(def->driver, "vfio_ccw")) ++ if (!def->driver || ++ (STRNEQ(def->driver, "io_subchannel") && ++ STRNEQ(def->driver, "vfio_ccw"))) + return -1; + + if (udevGetCCWAddress(def->sysfs_path, &def->caps->data) < 0) +-- +2.28.0 + diff --git a/SOURCES/libvirt-util-Add-phys_port_name-support-on-virPCIGetNetName.patch b/SOURCES/libvirt-util-Add-phys_port_name-support-on-virPCIGetNetName.patch new file mode 100644 index 0000000..2cbe85e --- /dev/null +++ b/SOURCES/libvirt-util-Add-phys_port_name-support-on-virPCIGetNetName.patch @@ -0,0 +1,228 @@ +From cfe170216accf60938ff4ea9440a4ac78b0bd83f Mon Sep 17 00:00:00 2001 +Message-Id: <cfe170216accf60938ff4ea9440a4ac78b0bd83f@dist-git> +From: Dmytro Linkin <dlinkin@nvidia.com> +Date: Thu, 28 Jan 2021 23:17:29 -0500 +Subject: [PATCH] util: Add phys_port_name support on virPCIGetNetName + +virPCIGetNetName is used to get the name of the netdev associated with +a particular PCI device. This is used when we have a VF name, but need +the PF name in order to send a netlink command (e.g. in order to +get/set the MAC address of the VF). + +In simple cases there is a single netdev associated with any PCI +device, so it is easy to figure out the PF netdev for a VF - just look +for the PCI device that has the VF listed in its "virtfns" directory; +the only name in the "net" subdirectory of that PCI device's sysfs +directory is the PF netdev that is upstream of the VF in question. + +In some cases there can be more than one netdev in a PCI device's net +directory though. In the past, the only case of this was for SR-IOV +NICs that could have multiple PF's per PCI device. In this case, all +PF netdevs associated with a PCI address would be listed in the "net" +subdirectory of the PCI device's directory in sysfs. At the same time, +all VF netdevs and all PF netdevs have a phys_port_id in their sysfs, +so the way to learn the correct PF netdev for a particular VF netdev +is to search through the list of devices in the net subdirectory of +the PF's PCI device, looking for the one netdev with a "phys_port_id" +matching that of the VF netdev. + +But starting in kernel 5.8, the NVIDIA Mellanox driver began linking +the VFs' representor netdevs to the PF PCI address [1], and so the VF +representor netdevs would also show up in the net +subdirectory. However, all of the devices that do so also only have a +single PF netdev for any given PCI address. + +This means that the net directory of the PCI device can still hold +multiple net devices, but only one of them will be the PF netdev (the +others are VF representors): + +$ ls '/sys/bus/pci/devices/0000:82:00.0/net' +ens1f0 eth0 eth1 + +In this case the way to find the PF device is to look at the +"phys_port_name" attribute of each netdev in sysfs. All PF devices +have a phys_port_name matching a particular regex + + (p[0-9]+$)|(p[0-9]+s[0-9]+$) + +Since there can only be one PF in the entire list of devices, once we +match that regex, we've found the PF netdev. + +[1] - https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/ + commit/?id=123f0f53dd64b67e34142485fe866a8a581f12f1 + +Resolves: https://bugzilla.redhat.com/1918708 +Co-Authored-by: Moshe Levi <moshele@nvidia.com> +Signed-off-by: Dmytro Linkin <dlinkin@nvidia.com> +Reviewed-by: Adrian Chiris <adrianc@nvidia.com> +Reviewed-by: Laine Stump <laine@redhat.com> +(cherry picked from commit 5b1c525b1f3608156884aed0dc5e925306c1e260) + +Conflicts: src/util/virpci.c - upstream all DIR* were converted to use + g_autoptr, which permitted virPCIGetNetName() to be + simplified. Unfortunately, backporting this refactor would require + backporting an ever-ballooning set of patches, making the + possibility of causing a regression a very real danger. Instead, + one small refactor of virPCIGetName() that didn't affect any other + functions was backported, and this patch (adding phys_port_name + support) resolved the remaining conflicts by mimicking the current + upstream version of the function, but with all "return 0" replaced + by "ret = 0; goto cleanup;" and all "return -1" replaced by "goto + cleanup;" (the code at cleanup: just closes the DIR* and returns + the current value of ret). This will assure identical behavior to + upstream. +Signed-off-by: Laine Stump <laine@redhat.com> +Message-Id: <20210129041729.1076345-4-laine@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/util/virpci.c | 93 ++++++++++++++++++++++++++++------------------- + src/util/virpci.h | 5 +++ + 2 files changed, 61 insertions(+), 37 deletions(-) + +diff --git a/src/util/virpci.c b/src/util/virpci.c +index 00377eed31..d5c038b7fe 100644 +--- a/src/util/virpci.c ++++ b/src/util/virpci.c +@@ -2424,9 +2424,9 @@ virPCIDeviceAddressGetSysfsFile(virPCIDeviceAddressPtr addr, + * virPCIGetNetName: + * @device_link_sysfs_path: sysfs path to the PCI device + * @idx: used to choose which netdev when there are several +- * (ignored if physPortID is set) ++ * (ignored if physPortID is set or physPortName is available) + * @physPortID: match this string in the netdev's phys_port_id +- * (or NULL to ignore and use idx instead) ++ * (or NULL to ignore and use phys_port_name or idx instead) + * @netname: used to return the name of the netdev + * (set to NULL (but returns success) if there is no netdev) + * +@@ -2460,6 +2460,14 @@ virPCIGetNetName(const char *device_link_sysfs_path, + } + + while (virDirRead(dir, &entry, pcidev_sysfs_net_path) > 0) { ++ /* save the first entry we find to use as a failsafe ++ * in case we don't match the phys_port_id. This is ++ * needed because some NIC drivers (e.g. i40e) ++ * implement phys_port_id for PFs, but not for VFs ++ */ ++ if (!firstEntryName) ++ firstEntryName = g_strdup(entry->d_name); ++ + /* if the caller sent a physPortID, compare it to the + * physportID of this netdev. If not, look for entry[idx]. + */ +@@ -2470,50 +2478,61 @@ virPCIGetNetName(const char *device_link_sysfs_path, + goto cleanup; + + /* if this one doesn't match, keep looking */ +- if (STRNEQ_NULLABLE(physPortID, thisPhysPortID)) { +- /* save the first entry we find to use as a failsafe +- * in case we don't match the phys_port_id. This is +- * needed because some NIC drivers (e.g. i40e) +- * implement phys_port_id for PFs, but not for VFs +- */ +- if (!firstEntryName) +- firstEntryName = g_strdup(entry->d_name); +- ++ if (STRNEQ_NULLABLE(physPortID, thisPhysPortID)) + continue; +- } ++ + } else { +- if (i++ < idx) +- continue; +- } ++ /* Most switch devices use phys_port_name instead of ++ * phys_port_id. ++ * NOTE: VFs' representors net devices can be linked to PF's PCI ++ * device, which mean that there'll be multiple net devices ++ * instances and to get a proper net device need to match on ++ * specific regex. ++ * To get PF netdev, for ex., used following regex: ++ * "(p[0-9]+$)|(p[0-9]+s[0-9]+$)" ++ * or to get exact VF's netdev next regex is used: ++ * "pf0vf1$" ++ */ ++ g_autofree char *thisPhysPortName = NULL; + +- *netname = g_strdup(entry->d_name); ++ if (virNetDevGetPhysPortName(entry->d_name, &thisPhysPortName) < 0) ++ goto cleanup; + +- ret = 0; +- break; +- } ++ if (thisPhysPortName) { ++ ++ /* if this one doesn't match, keep looking */ ++ if (!virStringMatch(thisPhysPortName, VIR_PF_PHYS_PORT_NAME_REGEX)) ++ continue; + +- if (ret < 0) { +- if (physPortID) { +- if (firstEntryName) { +- /* we didn't match the provided phys_port_id, but this +- * is probably because phys_port_id isn't implemented +- * for this NIC driver, so just return the first +- * (probably only) netname we found. +- */ +- *netname = firstEntryName; +- firstEntryName = NULL; +- ret = 0; + } else { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Could not find network device with " +- "phys_port_id '%s' under PCI device at %s"), +- physPortID, device_link_sysfs_path); ++ ++ if (i++ < idx) ++ continue; + } +- } else { +- ret = 0; /* no netdev at the given index is *not* an error */ + } ++ ++ *netname = g_strdup(entry->d_name); ++ ret = 0; ++ goto cleanup; + } +- cleanup: ++ ++ if (firstEntryName) { ++ /* we didn't match the provided phys_port_id / find a ++ * phys_port_name matching VIR_PF_PHYS_PORT_NAME_REGEX / find ++ * as many net devices as the value of idx, but this is ++ * probably because phys_port_id / phys_port_name isn't ++ * implemented for this NIC driver, so just return the first ++ * (probably only) netname we found. ++ */ ++ *netname = g_steal_pointer(&firstEntryName); ++ ret = 0; ++ goto cleanup; ++ } ++ ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("Could not find any network device under PCI device at %s"), ++ device_link_sysfs_path); ++cleanup: + VIR_DIR_CLOSE(dir); + return ret; + } +diff --git a/src/util/virpci.h b/src/util/virpci.h +index f6796fc422..e47c766918 100644 +--- a/src/util/virpci.h ++++ b/src/util/virpci.h +@@ -49,6 +49,11 @@ struct _virZPCIDeviceAddress { + + #define VIR_PCI_DEVICE_ADDRESS_FMT "%04x:%02x:%02x.%d" + ++/* Represents format of PF's phys_port_name in switchdev mode: ++ * 'p%u' or 'p%us%u'. New line checked since value is readed from sysfs file. ++ */ ++#define VIR_PF_PHYS_PORT_NAME_REGEX "(p[0-9]+$)|(p[0-9]+s[0-9]+$)" ++ + struct _virPCIDeviceAddress { + unsigned int domain; + unsigned int bus; +-- +2.30.0 + diff --git a/SOURCES/libvirt-util-add-virNetDevGetPhysPortName.patch b/SOURCES/libvirt-util-add-virNetDevGetPhysPortName.patch new file mode 100644 index 0000000..15a794f --- /dev/null +++ b/SOURCES/libvirt-util-add-virNetDevGetPhysPortName.patch @@ -0,0 +1,143 @@ +From 1b2014e2206b30a743a75908a129e444761726a7 Mon Sep 17 00:00:00 2001 +Message-Id: <1b2014e2206b30a743a75908a129e444761726a7@dist-git> +From: Moshe Levi <moshele@nvidia.com> +Date: Thu, 28 Jan 2021 23:17:27 -0500 +Subject: [PATCH] util: add virNetDevGetPhysPortName + +This commit add virNetDevGetPhysPortName to read netdevice +phys_port_name from sysfs. It also refactor the code so +virNetDevGetPhysPortName and virNetDevGetPhysPortID will use +same method to read the netdevice sysfs. + +https://bugzilla.redhat.com/1918708 +Signed-off-by: Moshe Levi <moshele@nvidia.com> +Reviewed-by: Laine Stump <laine@redhat.com> +(cherry picked from commit 97ebb982453bc23759c5f180799d6f2207b81c80) + +Conflicts: src/util/virnetdev.c was converted to use g_autofree upstream. + This patch removes the need for the g_autofreed variable. +Signed-off-by: Laine Stump <laine@redhat.com> +Message-Id: <20210129041729.1076345-2-laine@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/util/virnetdev.c | 72 +++++++++++++++++++++++++++++++++----------- + src/util/virnetdev.h | 4 +++ + 2 files changed, 59 insertions(+), 17 deletions(-) + +diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c +index e2aad07c24..52c9343d63 100644 +--- a/src/util/virnetdev.c ++++ b/src/util/virnetdev.c +@@ -1143,6 +1143,29 @@ virNetDevGetPCIDevice(const char *devName) + } + + ++/* A wrapper to get content of file from ifname SYSFS_NET_DIR ++ */ ++static int ++virNetDevGetSysfsFileValue(const char *ifname, ++ const char *fileName, ++ char **sysfsFileData) ++{ ++ g_autofree char *sysfsFile = NULL; ++ ++ *sysfsFileData = NULL; ++ ++ if (virNetDevSysfsFile(&sysfsFile, ifname, fileName) < 0) ++ return -1; ++ ++ /* a failure to read just means the driver doesn't support ++ * <fileName>, so set success now and ignore the return from ++ * virFileReadAllQuiet(). ++ */ ++ ++ ignore_value(virFileReadAllQuiet(sysfsFile, 1024, sysfsFileData)); ++ return 0; ++} ++ + /** + * virNetDevGetPhysPortID: + * +@@ -1161,25 +1184,29 @@ int + virNetDevGetPhysPortID(const char *ifname, + char **physPortID) + { +- int ret = -1; +- char *physPortIDFile = NULL; +- +- *physPortID = NULL; +- +- if (virNetDevSysfsFile(&physPortIDFile, ifname, "phys_port_id") < 0) +- goto cleanup; +- +- /* a failure to read just means the driver doesn't support +- * phys_port_id, so set success now and ignore the return from +- * virFileReadAllQuiet(). +- */ +- ret = 0; ++ return virNetDevGetSysfsFileValue(ifname, "phys_port_id", physPortID); ++} + +- ignore_value(virFileReadAllQuiet(physPortIDFile, 1024, physPortID)); + +- cleanup: +- VIR_FREE(physPortIDFile); +- return ret; ++/** ++ * virNetDevGetPhysPortName: ++ * ++ * @ifname: name of a netdev ++ * ++ * @physPortName: pointer to char* that will receive @ifname's ++ * phys_port_name from sysfs (null terminated ++ * string). Could be NULL if @ifname's net driver doesn't ++ * support phys_port_name (most netdev drivers ++ * don't). Caller is responsible for freeing the string ++ * when finished. ++ * ++ * Returns 0 on success or -1 on failure. ++ */ ++int ++virNetDevGetPhysPortName(const char *ifname, ++ char **physPortName) ++{ ++ return virNetDevGetSysfsFileValue(ifname, "phys_port_name", physPortName); + } + + +@@ -1461,6 +1488,17 @@ virNetDevGetPhysPortID(const char *ifname G_GNUC_UNUSED, + return 0; + } + ++int ++virNetDevGetPhysPortName(const char *ifname G_GNUC_UNUSED, ++ char **physPortName) ++{ ++ /* this actually should never be called, and is just here to ++ * satisfy the linker. ++ */ ++ *physPortName = NULL; ++ return 0; ++} ++ + int + virNetDevGetVirtualFunctions(const char *pfname G_GNUC_UNUSED, + char ***vfname G_GNUC_UNUSED, +diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h +index 24b41498ed..26fe76cc2c 100644 +--- a/src/util/virnetdev.h ++++ b/src/util/virnetdev.h +@@ -227,6 +227,10 @@ int virNetDevGetPhysPortID(const char *ifname, + char **physPortID) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) + G_GNUC_WARN_UNUSED_RESULT; ++int virNetDevGetPhysPortName(const char *ifname, ++ char **physPortName) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ++ G_GNUC_WARN_UNUSED_RESULT; + + int virNetDevGetVirtualFunctions(const char *pfname, + char ***vfname, +-- +2.30.0 + diff --git a/SOURCES/libvirt-util-always-check-for-ebtables-iptables-binaries-even-when-using-firewalld.patch b/SOURCES/libvirt-util-always-check-for-ebtables-iptables-binaries-even-when-using-firewalld.patch new file mode 100644 index 0000000..f4fe465 --- /dev/null +++ b/SOURCES/libvirt-util-always-check-for-ebtables-iptables-binaries-even-when-using-firewalld.patch @@ -0,0 +1,108 @@ +From 36a12736f39da72dba98b843def645e5e4ed0afb Mon Sep 17 00:00:00 2001 +Message-Id: <36a12736f39da72dba98b843def645e5e4ed0afb@dist-git> +From: Laine Stump <laine@redhat.com> +Date: Fri, 15 Jan 2021 22:51:49 -0500 +Subject: [PATCH] util: always check for ebtables/iptables binaries, even when + using firewalld + +Even though *we* don't call ebtables/iptables/ip6tables (yet) when the +firewalld backend is selected, firewalld does, so these binaries need +to be there; let's check for them. (Also, the patch after this one is +going to start execing those binaries directly rather than via +firewalld). + +https://bugzilla.redhat.com/1607929 + +Signed-off-by: Laine Stump <laine@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit 56dd128bd06c38fab4256a098124d47d803e919a) +Message-Id: <20210116035151.1066734-7-laine@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/util/virfirewall.c | 56 ++++++++++++++++++++---------------------- + 1 file changed, 26 insertions(+), 30 deletions(-) + +diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c +index 2e3b02402e..520d515c11 100644 +--- a/src/util/virfirewall.c ++++ b/src/util/virfirewall.c +@@ -100,24 +100,38 @@ VIR_ONCE_GLOBAL_INIT(virFirewall); + static int + virFirewallValidateBackend(virFirewallBackend backend) + { +- VIR_DEBUG("Validating backend %d", backend); ++ const char *commands[] = { ++ IPTABLES_PATH, IP6TABLES_PATH, EBTABLES_PATH ++ }; ++ size_t i; ++ ++ for (i = 0; i < G_N_ELEMENTS(commands); i++) { ++ if (!virFileIsExecutable(commands[i])) { ++ virReportSystemError(errno, ++ _("%s not available, firewall backend will not function"), ++ commands[i]); ++ return -1; ++ } ++ } ++ VIR_DEBUG("found iptables/ip6tables/ebtables"); ++ + if (backend == VIR_FIREWALL_BACKEND_AUTOMATIC || + backend == VIR_FIREWALL_BACKEND_FIREWALLD) { + int rv = virFirewallDIsRegistered(); + + VIR_DEBUG("Firewalld is registered ? %d", rv); +- if (rv < 0) { +- if (rv == -2) { +- if (backend == VIR_FIREWALL_BACKEND_FIREWALLD) { +- virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +- _("firewalld firewall backend requested, but service is not running")); +- return -1; +- } else { +- VIR_DEBUG("firewalld service not running, trying direct backend"); +- backend = VIR_FIREWALL_BACKEND_DIRECT; +- } +- } else { ++ ++ if (rv == -1) ++ return -1; ++ ++ if (rv == -2) { ++ if (backend == VIR_FIREWALL_BACKEND_FIREWALLD) { ++ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", ++ _("firewalld backend requested, but service is not running")); + return -1; ++ } else { ++ VIR_DEBUG("firewalld service not running, using direct backend"); ++ backend = VIR_FIREWALL_BACKEND_DIRECT; + } + } else { + VIR_DEBUG("firewalld service running, using firewalld backend"); +@@ -125,25 +139,7 @@ virFirewallValidateBackend(virFirewallBackend backend) + } + } + +- if (backend == VIR_FIREWALL_BACKEND_DIRECT) { +- const char *commands[] = { +- IPTABLES_PATH, IP6TABLES_PATH, EBTABLES_PATH +- }; +- size_t i; +- +- for (i = 0; i < G_N_ELEMENTS(commands); i++) { +- if (!virFileIsExecutable(commands[i])) { +- virReportSystemError(errno, +- _("direct firewall backend requested, but %s is not available"), +- commands[i]); +- return -1; +- } +- } +- VIR_DEBUG("found iptables/ip6tables/ebtables, using direct backend"); +- } +- + currentBackend = backend; +- + return 0; + } + +-- +2.30.0 + diff --git a/SOURCES/libvirt-util-assign-tap-device-names-using-a-monotonically-increasing-integer.patch b/SOURCES/libvirt-util-assign-tap-device-names-using-a-monotonically-increasing-integer.patch new file mode 100644 index 0000000..1a1e009 --- /dev/null +++ b/SOURCES/libvirt-util-assign-tap-device-names-using-a-monotonically-increasing-integer.patch @@ -0,0 +1,280 @@ +From 37b1acb1c820421d62b1416d90138bae7961bfb7 Mon Sep 17 00:00:00 2001 +Message-Id: <37b1acb1c820421d62b1416d90138bae7961bfb7@dist-git> +From: Laine Stump <laine@redhat.com> +Date: Sat, 12 Dec 2020 22:04:52 -0500 +Subject: [PATCH] util: assign tap device names using a monotonically + increasing integer + +When creating a standard tap device, if provided with an ifname that +contains "%d", rather than taking that literally as the name to use +for the new device, the kernel will instead use that string as a +template, and search for the lowest number that could be put in place +of %d and produce an otherwise unused and unique name for the new +device. For example, if there is no tap device name given in the XML, +libvirt will always send "vnet%d" as the device name, and the kernel +will create new devices named "vnet0", "vnet1", etc. If one of those +devices is deleted, creating a "hole" in the name list, the kernel +will always attempt to reuse the name in the hole first before using a +name with a higher number (i.e. it finds the lowest possible unused +number). + +The problem with this, as described in the previous patch dealing with +macvtap device naming, is that it makes "immediate reuse" of a newly +freed tap device name *much* more common, and in the aftermath of +deleting a tap device, there is some other necessary cleanup of things +which are named based on the device name (nwfilter rules, bandwidth +rules, OVS switch ports, to name a few) that could end up stomping +over the top of the setup of a new device of the same name for a +different guest. + +Since the kernel "create a name based on a template" functionality for +tap devices doesn't exist for macvtap, this patch for standard tap +devices is a bit different from the previous patch for macvtap - in +particular there was no previous "bitmap ID reservation system" or +overly-complex retry loop that needed to be removed. We simply find +and unused name, and pass that name on to the kernel instead of +"vnet%d". + +This counter is also wrapped when either it gets to INT_MAX or if the +full name would overflow IFNAMSIZ-1 characters. In the case of +"vnet%d" and a 32 bit int, we would reach INT_MAX first, but possibly +someday someone will change the name from vnet to something else. + +(NB: It is still possible for a user to provide their own +parameterized template name (e.g. "mytap%d") in the XML, and libvirt +will just pass that through to the kernel as it always has.) + +Signed-off-by: Laine Stump <laine@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit 95089f481e003d971fe0a082018216c58c1b80e5) + +https://bugzilla.redhat.com/1874304 +Signed-off-by: Laine Stump <laine@redhat.com> +Message-Id: <20201213030453.48851-3-laine@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +--- + src/libvirt_private.syms | 1 + + src/qemu/qemu_process.c | 20 +++++++- + src/util/virnetdevtap.c | 108 ++++++++++++++++++++++++++++++++++++++- + src/util/virnetdevtap.h | 4 ++ + 4 files changed, 130 insertions(+), 3 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 1c66c40f86..d6598c2514 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2638,6 +2638,7 @@ virNetDevTapGetName; + virNetDevTapGetRealDeviceName; + virNetDevTapInterfaceStats; + virNetDevTapReattachBridge; ++virNetDevTapReserveName; + + + # util/virnetdevveth.h +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index b49a463c02..f90096e68d 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -3287,8 +3287,26 @@ qemuProcessNotifyNets(virDomainDefPtr def) + * domain to be unceremoniously killed, which would be *very* + * impolite. + */ +- if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) ++ switch (virDomainNetGetActualType(net)) { ++ case VIR_DOMAIN_NET_TYPE_DIRECT: + virNetDevMacVLanReserveName(net->ifname); ++ break; ++ case VIR_DOMAIN_NET_TYPE_BRIDGE: ++ case VIR_DOMAIN_NET_TYPE_NETWORK: ++ case VIR_DOMAIN_NET_TYPE_ETHERNET: ++ virNetDevTapReserveName(net->ifname); ++ break; ++ case VIR_DOMAIN_NET_TYPE_USER: ++ case VIR_DOMAIN_NET_TYPE_VHOSTUSER: ++ case VIR_DOMAIN_NET_TYPE_SERVER: ++ case VIR_DOMAIN_NET_TYPE_CLIENT: ++ case VIR_DOMAIN_NET_TYPE_MCAST: ++ case VIR_DOMAIN_NET_TYPE_INTERNAL: ++ case VIR_DOMAIN_NET_TYPE_HOSTDEV: ++ case VIR_DOMAIN_NET_TYPE_UDP: ++ case VIR_DOMAIN_NET_TYPE_LAST: ++ break; ++ } + + if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) { + if (!conn && !(conn = virGetConnectNetwork())) +diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c +index 6a16b58d60..fd4b70df30 100644 +--- a/src/util/virnetdevtap.c ++++ b/src/util/virnetdevtap.c +@@ -45,11 +45,51 @@ + #if defined(HAVE_GETIFADDRS) && defined(AF_LINK) + # include <ifaddrs.h> + #endif ++#include <math.h> + + #define VIR_FROM_THIS VIR_FROM_NONE + + VIR_LOG_INIT("util.netdevtap"); + ++virMutex virNetDevTapCreateMutex = VIR_MUTEX_INITIALIZER; ++static int virNetDevTapLastID = -1; /* not "unsigned" because callers use %d */ ++ ++ ++/** ++ * virNetDevTapReserveName: ++ * @name: name of an existing tap device ++ * ++ * Set the value of virNetDevTapLastID to assure that any new tap ++ * device created with an autogenerated name will use a number higher ++ * than the number in the given tap device name. ++ * ++ * Returns nothing. ++ */ ++void ++virNetDevTapReserveName(const char *name) ++{ ++ unsigned int id; ++ const char *idstr = NULL; ++ ++ ++ if (STRPREFIX(name, VIR_NET_GENERATED_TAP_PREFIX)) { ++ ++ VIR_INFO("marking device in use: '%s'", name); ++ ++ idstr = name + strlen(VIR_NET_GENERATED_TAP_PREFIX); ++ ++ if (virStrToLong_ui(idstr, NULL, 10, &id) >= 0) { ++ virMutexLock(&virNetDevTapCreateMutex); ++ ++ if (virNetDevTapLastID < (int)id) ++ virNetDevTapLastID = id; ++ ++ virMutexUnlock(&virNetDevTapCreateMutex); ++ } ++ } ++} ++ ++ + /** + * virNetDevTapGetName: + * @tapfd: a tun/tap file descriptor +@@ -200,6 +240,55 @@ virNetDevProbeVnetHdr(int tapfd) + + + #ifdef TUNSETIFF ++/** ++ * virNetDevTapGenerateName: ++ * @ifname: pointer to pointer to string containing template ++ * ++ * generate a new (currently unused) name for a new tap device based ++ * on the templace string in @ifname - replace %d with ++ * ++virNetDevTapLastID, and keep trying new values until one is found ++ * that doesn't already exist, or we've tried 10000 different ++ * names. Once a usable name is found, replace the template with the ++ * actual name. ++ * ++ * Returns 0 on success, -1 on failure. ++ */ ++static int ++virNetDevTapGenerateName(char **ifname) ++{ ++ int id; ++ double maxIDd = pow(10, IFNAMSIZ - 1 - strlen(VIR_NET_GENERATED_TAP_PREFIX)); ++ int maxID = INT_MAX; ++ int attempts = 0; ++ ++ if (maxIDd <= (double)INT_MAX) ++ maxID = (int)maxIDd; ++ ++ do { ++ g_autofree char *try = NULL; ++ ++ id = ++virNetDevTapLastID; ++ ++ /* reset before overflow */ ++ if (virNetDevTapLastID >= maxID) ++ virNetDevTapLastID = -1; ++ ++ try = g_strdup_printf(*ifname, id); ++ ++ if (!virNetDevExists(try)) { ++ g_free(*ifname); ++ *ifname = g_steal_pointer(&try); ++ return 0; ++ } ++ } while (++attempts < 10000); ++ ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("no unused %s names available"), ++ VIR_NET_GENERATED_TAP_PREFIX); ++ return -1; ++} ++ ++ + /** + * virNetDevTapCreate: + * @ifname: the interface name +@@ -226,10 +315,22 @@ int virNetDevTapCreate(char **ifname, + size_t tapfdSize, + unsigned int flags) + { +- size_t i; ++ size_t i = 0; + struct ifreq ifr; + int ret = -1; +- int fd; ++ int fd = 0; ++ ++ virMutexLock(&virNetDevTapCreateMutex); ++ ++ /* if ifname is "vnet%d", then auto-generate a name for the new ++ * device (the kernel could do this for us, but has a bad habit of ++ * immediately re-using names that have just been released, which ++ * can lead to race conditions). ++ */ ++ if (STREQ(*ifname, VIR_NET_GENERATED_TAP_PREFIX "%d") && ++ virNetDevTapGenerateName(ifname) < 0) { ++ goto cleanup; ++ } + + if (!tunpath) + tunpath = "/dev/net/tun"; +@@ -295,9 +396,11 @@ int virNetDevTapCreate(char **ifname, + tapfd[i] = fd; + } + ++ VIR_INFO("created device: '%s'", *ifname); + ret = 0; + + cleanup: ++ virMutexUnlock(&virNetDevTapCreateMutex); + if (ret < 0) { + VIR_FORCE_CLOSE(fd); + while (i--) +@@ -347,6 +450,7 @@ int virNetDevTapDelete(const char *ifname, + goto cleanup; + } + ++ VIR_INFO("delete device: '%s'", ifname); + ret = 0; + + cleanup: +diff --git a/src/util/virnetdevtap.h b/src/util/virnetdevtap.h +index cae8e61861..2994c9ca71 100644 +--- a/src/util/virnetdevtap.h ++++ b/src/util/virnetdevtap.h +@@ -29,6 +29,10 @@ + # define VIR_NETDEV_TAP_REQUIRE_MANUAL_CLEANUP 1 + #endif + ++void ++virNetDevTapReserveName(const char *name) ++ ATTRIBUTE_NONNULL(1); ++ + int virNetDevTapCreate(char **ifname, + const char *tunpath, + int *tapfd, +-- +2.29.2 + diff --git a/SOURCES/libvirt-util-avoid-manual-VIR_FREE-of-a-g_autofree-pointer-in-virPCIGetName.patch b/SOURCES/libvirt-util-avoid-manual-VIR_FREE-of-a-g_autofree-pointer-in-virPCIGetName.patch new file mode 100644 index 0000000..bb987c0 --- /dev/null +++ b/SOURCES/libvirt-util-avoid-manual-VIR_FREE-of-a-g_autofree-pointer-in-virPCIGetName.patch @@ -0,0 +1,52 @@ +From 4eed301c16a93fdcc6867823a88406e9578c1da7 Mon Sep 17 00:00:00 2001 +Message-Id: <4eed301c16a93fdcc6867823a88406e9578c1da7@dist-git> +From: Laine Stump <laine@redhat.com> +Date: Thu, 28 Jan 2021 23:17:28 -0500 +Subject: [PATCH] util: avoid manual VIR_FREE of a g_autofree pointer in + virPCIGetName() + +thisPhysPortID is only used inside a conditional, so reduce its scope +to just the body of that conditional, which will eliminate the need +for the undesirable manual VIR_FREE(). + +https://bugzilla.redhat.com/1918708 +Signed-off-by: Laine Stump <laine@redhat.com> +Reviewed-by: Erik Skultety <eskultet@redhat.com> +Reviewed-by: Peter Krempa <pkrempa@redhat.com> +(cherry picked from commit fefd478644a2ad2951491552081cd53b6ecd4223) +Message-Id: <20210129041729.1076345-3-laine@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/util/virpci.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/util/virpci.c b/src/util/virpci.c +index 0b1222373e..00377eed31 100644 +--- a/src/util/virpci.c ++++ b/src/util/virpci.c +@@ -2440,7 +2440,6 @@ virPCIGetNetName(const char *device_link_sysfs_path, + { + g_autofree char *pcidev_sysfs_net_path = NULL; + g_autofree char *firstEntryName = NULL; +- g_autofree char *thisPhysPortID = NULL; + int ret = -1; + DIR *dir = NULL; + struct dirent *entry = NULL; +@@ -2465,12 +2464,13 @@ virPCIGetNetName(const char *device_link_sysfs_path, + * physportID of this netdev. If not, look for entry[idx]. + */ + if (physPortID) { ++ g_autofree char *thisPhysPortID = NULL; ++ + if (virNetDevGetPhysPortID(entry->d_name, &thisPhysPortID) < 0) + goto cleanup; + + /* if this one doesn't match, keep looking */ + if (STRNEQ_NULLABLE(physPortID, thisPhysPortID)) { +- VIR_FREE(thisPhysPortID); + /* save the first entry we find to use as a failsafe + * in case we don't match the phys_port_id. This is + * needed because some NIC drivers (e.g. i40e) +-- +2.30.0 + diff --git a/SOURCES/libvirt-util-call-iptables-directly-rather-than-via-firewalld.patch b/SOURCES/libvirt-util-call-iptables-directly-rather-than-via-firewalld.patch new file mode 100644 index 0000000..3ec098c --- /dev/null +++ b/SOURCES/libvirt-util-call-iptables-directly-rather-than-via-firewalld.patch @@ -0,0 +1,228 @@ +From 4d8a10886f4dffd08fcf6a93694e12f76a2afd66 Mon Sep 17 00:00:00 2001 +Message-Id: <4d8a10886f4dffd08fcf6a93694e12f76a2afd66@dist-git> +From: Laine Stump <laine@redhat.com> +Date: Fri, 15 Jan 2021 22:51:51 -0500 +Subject: [PATCH] util: call iptables directly rather than via firewalld + +When libvirt added support for firewalld, we were unable to use +firewalld's higher level rules, because they weren't detailed enough +and could not be applied to the iptables FORWARD or OUTPUT chains +(only to the INPUT chain). Instead we changed our code so that rather +than running the iptables/ip6tables/ebtables binaries ourselves, we +would send these commands to firewalld as "passthrough commands", and +firewalld would run the appropriate program on our behalf. + +This was done under the assumption that firewalld was somehow tracking +all these rules, and that this tracking was benefitting proper +operation of firewalld and the system in general. + +Several years later this came up in a discussion on IRC, and we +learned from the firewalld developers that, in fact, adding iptables +and ebtables rules with firewalld's passthrough commands actually has +*no* advantage; firewalld doesn't keep track of these rules in any +way, and doesn't use them to tailor the construction of its own rules. + +Meanwhile, users have been complaining for some time that whenever +firewalld is restarted on a system with libvirt virtual networks +and/or nwfilter rules active, the system logs would be flooded with +warning messages whining that [lots of different rules] could not be +deleted because they didn't exist. For example: + +firewalld[3536040]: WARNING: COMMAND_FAILED: + '/usr/sbin/iptables -w10 -w --table filter --delete LIBVIRT_OUT + --out-interface virbr4 --protocol udp --destination-port 68 + --jump ACCEPT' failed: iptables: Bad rule + (does a matching rule exist in that chain?). + +See: + + https://bugzilla.redhat.com/1607929 (RHEL8) + https://bugzilla.redhat.com/1790837 (RHEL8-AV) + +for many more examples and a discussion) + +Note that these messages are created by iptables, but are logged by +firewalld - when an iptables/ebtables command fails, firewalld grabs +whatever is in stderr of the program, and spits it out to the system +log as a warning. We've requested that firewalld not do this (and +instead leave it up to the calling application to do the appropriate +logging), but this request has been respectfully denied. + +But combining the two problems above ( 1) firewalld doesn't do +anything useful when you use it as a proxy to add/remove iptables +rules, 2) firewalld often insists on logging lots of +annoying/misleading/useless "error" messages when you use it as a +proxy to remove iptables rules that don't already exist), leads to a +solution - simply stop using firewalld to add and remove iptables +rules. Instead, exec iptables/ip6tables/ebtables directly in the same +way we do when firewalld isn't active. + +We still need to keep track of whether or not firewalld is active, as +there are some things that must be done, e.g. we need to add some +actual firewalld rules in the firewalld "libvirt" zone, and we need to +take notice when firewalld restarts, so that we can reload all our +rules. + +This patch doesn't remove the infrastructure that allows having +different firewall backends that perform their functions in different +ways, as that will very possibly come in handy in the future when we +want to have an nftables direct backend, and possibly a "pure" +firewalld backend (now that firewalld supports more complex rules, and +can add those rules to the FORWARD and OUTPUT chains). Instead, it +just changes the action when the selected backend is "firewalld" so +that it adds rules directly rather than through firewalld, while +leaving as much of the existing code intact as possible. + +In order for tests to still pass, virfirewalltest also had to be +modified to behave in a different way (i.e. by capturing the generated +commandline as it does for the DIRECT backend, rather than capturing +dbus messages using a mocked dbus API). + +Signed-off-by: Laine Stump <laine@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit b19863640d10b47b7c4a7cbadb21f196d61d96a2) +Message-Id: <20210116035151.1066734-9-laine@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/util/virfirewall.c | 13 +++++++++++-- + tests/virfirewalltest.c | 30 ++++++++++++++++++++---------- + 2 files changed, 31 insertions(+), 12 deletions(-) + +diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c +index 66d20d3f17..2ea821ec17 100644 +--- a/src/util/virfirewall.c ++++ b/src/util/virfirewall.c +@@ -644,7 +644,7 @@ virFirewallApplyRuleDirect(virFirewallRulePtr rule, + } + + +-static int ++static int G_GNUC_UNUSED + virFirewallApplyRuleFirewallD(virFirewallRulePtr rule, + bool ignoreErrors, + char **output) +@@ -702,7 +702,16 @@ virFirewallApplyRule(virFirewallPtr firewall, + return -1; + break; + case VIR_FIREWALL_BACKEND_FIREWALLD: +- if (virFirewallApplyRuleFirewallD(rule, ignoreErrors, &output) < 0) ++ /* Since we are using raw iptables rules, there is no ++ * advantage to going through firewalld, so instead just add ++ * them directly rather that via dbus calls to firewalld. This ++ * has the useful side effect of eliminating extra unwanted ++ * warning messages in the system logs when trying to delete ++ * rules that don't exist (which is something that happens ++ * often when libvirtd is started, and *always* when firewalld ++ * is restarted) ++ */ ++ if (virFirewallApplyRuleDirect(rule, ignoreErrors, &output) < 0) + return -1; + break; + +diff --git a/tests/virfirewalltest.c b/tests/virfirewalltest.c +index 40e7f4f00b..1036353579 100644 +--- a/tests/virfirewalltest.c ++++ b/tests/virfirewalltest.c +@@ -214,7 +214,8 @@ testFirewallSingleGroup(const void *opaque) + if (virFirewallSetBackend(data->tryBackend) < 0) + goto cleanup; + +- if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) ++ if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT || ++ data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) + virCommandSetDryRun(&cmdbuf, NULL, NULL); + else + fwBuf = &cmdbuf; +@@ -271,7 +272,8 @@ testFirewallRemoveRule(const void *opaque) + if (virFirewallSetBackend(data->tryBackend) < 0) + goto cleanup; + +- if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) ++ if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT || ++ data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) + virCommandSetDryRun(&cmdbuf, NULL, NULL); + else + fwBuf = &cmdbuf; +@@ -335,7 +337,8 @@ testFirewallManyGroups(const void *opaque G_GNUC_UNUSED) + if (virFirewallSetBackend(data->tryBackend) < 0) + goto cleanup; + +- if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) ++ if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT || ++ data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) + virCommandSetDryRun(&cmdbuf, NULL, NULL); + else + fwBuf = &cmdbuf; +@@ -426,7 +429,8 @@ testFirewallIgnoreFailGroup(const void *opaque G_GNUC_UNUSED) + if (virFirewallSetBackend(data->tryBackend) < 0) + goto cleanup; + +- if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) { ++ if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT || ++ data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) { + virCommandSetDryRun(&cmdbuf, testFirewallRollbackHook, NULL); + } else { + fwBuf = &cmdbuf; +@@ -498,7 +502,8 @@ testFirewallIgnoreFailRule(const void *opaque G_GNUC_UNUSED) + if (virFirewallSetBackend(data->tryBackend) < 0) + goto cleanup; + +- if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) { ++ if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT || ++ data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) { + virCommandSetDryRun(&cmdbuf, testFirewallRollbackHook, NULL); + } else { + fwBuf = &cmdbuf; +@@ -567,7 +572,8 @@ testFirewallNoRollback(const void *opaque G_GNUC_UNUSED) + if (virFirewallSetBackend(data->tryBackend) < 0) + goto cleanup; + +- if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) { ++ if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT || ++ data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) { + virCommandSetDryRun(&cmdbuf, testFirewallRollbackHook, NULL); + } else { + fwBuf = &cmdbuf; +@@ -634,7 +640,8 @@ testFirewallSingleRollback(const void *opaque G_GNUC_UNUSED) + if (virFirewallSetBackend(data->tryBackend) < 0) + goto cleanup; + +- if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) { ++ if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT || ++ data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) { + virCommandSetDryRun(&cmdbuf, testFirewallRollbackHook, NULL); + } else { + fwError = true; +@@ -717,7 +724,8 @@ testFirewallManyRollback(const void *opaque G_GNUC_UNUSED) + if (virFirewallSetBackend(data->tryBackend) < 0) + goto cleanup; + +- if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) { ++ if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT || ++ data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) { + virCommandSetDryRun(&cmdbuf, testFirewallRollbackHook, NULL); + } else { + fwBuf = &cmdbuf; +@@ -808,7 +816,8 @@ testFirewallChainedRollback(const void *opaque G_GNUC_UNUSED) + if (virFirewallSetBackend(data->tryBackend) < 0) + goto cleanup; + +- if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) { ++ if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT || ++ data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) { + virCommandSetDryRun(&cmdbuf, testFirewallRollbackHook, NULL); + } else { + fwBuf = &cmdbuf; +@@ -1007,7 +1016,8 @@ testFirewallQuery(const void *opaque G_GNUC_UNUSED) + if (virFirewallSetBackend(data->tryBackend) < 0) + goto cleanup; + +- if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT) { ++ if (data->expectBackend == VIR_FIREWALL_BACKEND_DIRECT || ++ data->expectBackend == VIR_FIREWALL_BACKEND_FIREWALLD) { + virCommandSetDryRun(&cmdbuf, testFirewallQueryHook, NULL); + } else { + fwBuf = &cmdbuf; +-- +2.30.0 + diff --git a/SOURCES/libvirt-util-fix-typo-in-VIR_MOCK_WRAP_RET_ARGS.patch b/SOURCES/libvirt-util-fix-typo-in-VIR_MOCK_WRAP_RET_ARGS.patch new file mode 100644 index 0000000..6a8ab2d --- /dev/null +++ b/SOURCES/libvirt-util-fix-typo-in-VIR_MOCK_WRAP_RET_ARGS.patch @@ -0,0 +1,39 @@ +From 15b1f63574db2100d433d283a975928f83bb0ecb Mon Sep 17 00:00:00 2001 +Message-Id: <15b1f63574db2100d433d283a975928f83bb0ecb@dist-git> +From: Laine Stump <laine@redhat.com> +Date: Fri, 15 Jan 2021 22:51:44 -0500 +Subject: [PATCH] util: fix typo in VIR_MOCK_WRAP_RET_ARGS() + +When virfirewalltest.c was first written in commit 3a0ca7de51 (March +2013), a conditional accidentally tested for "ipv4" instead of +"ipv6". Since the file ended up only testing ipv4 rules, this has +never made any difference in practice, but I'm making some other +changes in this file and just couldn't let it stand :-) + +https://bugzilla.redhat.com/1607929 + +Signed-off-by: Laine Stump <laine@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit 28a3deddddfe102b37f2e373bf4581c2ce8d2050) +Message-Id: <20210116035151.1066734-2-laine@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + tests/virfirewalltest.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/virfirewalltest.c b/tests/virfirewalltest.c +index c4827918c3..8aba127610 100644 +--- a/tests/virfirewalltest.c ++++ b/tests/virfirewalltest.c +@@ -129,7 +129,7 @@ VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block, + if (fwBuf) { + if (STREQ(type, "ipv4")) + virBufferAddLit(fwBuf, IPTABLES_PATH); +- else if (STREQ(type, "ipv4")) ++ else if (STREQ(type, "ipv6")) + virBufferAddLit(fwBuf, IP6TABLES_PATH); + else + virBufferAddLit(fwBuf, EBTABLES_PATH); +-- +2.30.0 + diff --git a/SOURCES/libvirt-util-replace-macvtap-name-reservation-bitmap-with-a-simple-counter.patch b/SOURCES/libvirt-util-replace-macvtap-name-reservation-bitmap-with-a-simple-counter.patch new file mode 100644 index 0000000..34969d8 --- /dev/null +++ b/SOURCES/libvirt-util-replace-macvtap-name-reservation-bitmap-with-a-simple-counter.patch @@ -0,0 +1,736 @@ +From 4238e5f0783c63802de79bc5ed2a1f49673ef2a3 Mon Sep 17 00:00:00 2001 +Message-Id: <4238e5f0783c63802de79bc5ed2a1f49673ef2a3@dist-git> +From: Laine Stump <laine@redhat.com> +Date: Sat, 12 Dec 2020 22:04:51 -0500 +Subject: [PATCH] util: replace macvtap name reservation bitmap with a simple + counter + +There have been some reports that, due to libvirt always trying to +assign the lowest numbered macvtap / tap device name possible, a new +guest would sometimes be started using the same tap device name as +previously used by another guest that is in the process of being +destroyed *as the new guest is starting. + +In some cases this has led to, for example, the old guest's +qemuProcessStop() code deleting a port from an OVS switch that had +just been re-added by the new guest (because the port name is based on +only the device name using the port). Similar problems can happen (and +I believe have) with nwfilter rules and bandwidth rules (which are +both instantiated based on the name of the tap device). + +A couple patches have been previously proposed to change the ordering +of startup and shutdown processing, or to put a mutex around +everything related to the tap/macvtap device name usage, but in the +end no matter what you do there will still be possible holes, because +the device could be deleted outside libvirt's control (for example, +regular tap devices are automatically deleted when the qemu process +terminates, and that isn't always initiated by libvirt but could +instead happen completely asynchronously - libvirt then has no control +over the ordering of shutdown operations, and no opportunity to +protect it with a mutex.) + +But this only happens if a new device is created at the same time as +one is being deleted. We can effectively eliminate the chance of this +happening if we end the practice of always looking for the lowest +numbered available device name, and instead just keep an integer that +is incremented each time we need a new device name. At some point it +will need to wrap back around to 0 (in order to avoid the IFNAMSIZ 15 +character limit if nothing else), and we can't guarantee that the new +name really will be the *least* recently used name, but "math" +suggests that it will be *much* less common that we'll try to re-use +the *most* recently used name. + +This patch implements such a counter for macvtap/macvlan, replacing +the existing, and much more complicated, "ID reservation" system. The +counter is set according to whatever macvtap/macvlan devices are +already in use by guests when libvirtd is started, incremented each +time a new device name is needed, and wraps back to 0 when either +INT_MAX is reached, or when the resulting device name would be longer +than IFNAMSIZ-1 characters (which actually is what happens when the +template for the device name is "maccvtap%d"). The result is that no +macvtap name will be re-used until the host has created (and possibly +destroyed) 99,999,999 devices. + +Signed-off-by: Laine Stump <laine@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit d7f38beb2ee072f1f19bb91fbafc9182ce9b069e) + +https://bugzilla.redhat.com/1874304 +Signed-off-by: Laine Stump <laine@redhat.com> +Message-Id: <20201213030453.48851-2-laine@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +--- + src/libvirt_private.syms | 1 - + src/libxl/libxl_driver.c | 2 +- + src/lxc/lxc_process.c | 2 +- + src/qemu/qemu_process.c | 2 +- + src/util/virnetdevmacvlan.c | 403 +++++++++++++----------------------- + src/util/virnetdevmacvlan.h | 6 +- + 6 files changed, 145 insertions(+), 271 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index fdd104cd25..1c66c40f86 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2604,7 +2604,6 @@ virNetDevMacVLanDelete; + virNetDevMacVLanDeleteWithVPortProfile; + virNetDevMacVLanIsMacvtap; + virNetDevMacVLanModeTypeFromString; +-virNetDevMacVLanReleaseName; + virNetDevMacVLanReserveName; + virNetDevMacVLanRestartWithVPortProfile; + virNetDevMacVLanTapOpen; +diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c +index 1449795494..9269e9b475 100644 +--- a/src/libxl/libxl_driver.c ++++ b/src/libxl/libxl_driver.c +@@ -367,7 +367,7 @@ libxlReconnectNotifyNets(virDomainDefPtr def) + * impolite. + */ + if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) +- ignore_value(virNetDevMacVLanReserveName(net->ifname, false)); ++ virNetDevMacVLanReserveName(net->ifname); + + if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) { + if (!conn && !(conn = virGetConnectNetwork())) +diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c +index 0a9ccdf9ec..114c40b0ea 100644 +--- a/src/lxc/lxc_process.c ++++ b/src/lxc/lxc_process.c +@@ -1638,7 +1638,7 @@ virLXCProcessReconnectNotifyNets(virDomainDefPtr def) + * impolite. + */ + if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) +- ignore_value(virNetDevMacVLanReserveName(net->ifname, false)); ++ virNetDevMacVLanReserveName(net->ifname); + + if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) { + if (!conn && !(conn = virGetConnectNetwork())) +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 95c0315e53..b49a463c02 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -3288,7 +3288,7 @@ qemuProcessNotifyNets(virDomainDefPtr def) + * impolite. + */ + if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT) +- ignore_value(virNetDevMacVLanReserveName(net->ifname, false)); ++ virNetDevMacVLanReserveName(net->ifname); + + if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) { + if (!conn && !(conn = virGetConnectNetwork())) +diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c +index 3ca568fb44..7046cbb04e 100644 +--- a/src/util/virnetdevmacvlan.c ++++ b/src/util/virnetdevmacvlan.c +@@ -47,6 +47,7 @@ VIR_ENUM_IMPL(virNetDevMacVLanMode, + + # include <net/if.h> + # include <linux/if_tun.h> ++# include <math.h> + + /* Older kernels lacked this enum value. */ + # if !HAVE_DECL_MACVLAN_MODE_PASSTHRU +@@ -70,211 +71,121 @@ VIR_LOG_INIT("util.netdevmacvlan"); + ((flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? \ + VIR_NET_GENERATED_MACVTAP_PREFIX : VIR_NET_GENERATED_MACVLAN_PREFIX) + +-# define MACVLAN_MAX_ID 8191 + + virMutex virNetDevMacVLanCreateMutex = VIR_MUTEX_INITIALIZER; +-virBitmapPtr macvtapIDs = NULL; +-virBitmapPtr macvlanIDs = NULL; +- +-static int +-virNetDevMacVLanOnceInit(void) +-{ +- if (!macvtapIDs && +- !(macvtapIDs = virBitmapNew(MACVLAN_MAX_ID + 1))) +- return -1; +- if (!macvlanIDs && +- !(macvlanIDs = virBitmapNew(MACVLAN_MAX_ID + 1))) +- return -1; +- return 0; +-} +- +-VIR_ONCE_GLOBAL_INIT(virNetDevMacVLan); ++static int virNetDevMacVTapLastID = -1; ++static int virNetDevMacVLanLastID = -1; + + +-/** +- * virNetDevMacVLanReserveID: +- * +- * @id: id 0 - MACVLAN_MAX_ID+1 to reserve (or -1 for "first free") +- * @flags: set VIR_NETDEV_MACVLAN_CREATE_WITH_TAP for macvtapN else macvlanN +- * @quietFail: don't log an error if this name is already in-use +- * @nextFree: reserve the next free ID *after* @id rather than @id itself +- * +- * Reserve the indicated ID in the appropriate bitmap, or find the +- * first free ID if @id is -1. +- * +- * Returns newly reserved ID# on success, or -1 to indicate failure. +- */ +-static int +-virNetDevMacVLanReserveID(int id, unsigned int flags, +- bool quietFail, bool nextFree) ++static void ++virNetDevMacVLanReserveNameInternal(const char *name) + { +- virBitmapPtr bitmap; +- +- if (virNetDevMacVLanInitialize() < 0) +- return -1; +- +- bitmap = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? +- macvtapIDs : macvlanIDs; ++ unsigned int id; ++ const char *idstr = NULL; ++ int *lastID = NULL; ++ int len; + +- if (id > MACVLAN_MAX_ID) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("can't use name %s%d - out of range 0-%d"), +- VIR_NET_GENERATED_PREFIX, id, MACVLAN_MAX_ID); +- return -1; ++ if (STRPREFIX(name, VIR_NET_GENERATED_MACVTAP_PREFIX)) { ++ lastID = &virNetDevMacVTapLastID; ++ len = strlen(VIR_NET_GENERATED_MACVTAP_PREFIX); ++ } else if (STRPREFIX(name, VIR_NET_GENERATED_MACVLAN_PREFIX)) { ++ lastID = &virNetDevMacVTapLastID; ++ len = strlen(VIR_NET_GENERATED_MACVLAN_PREFIX); ++ } else { ++ return; + } + +- if ((id < 0 || nextFree) && +- (id = virBitmapNextClearBit(bitmap, id)) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("no unused %s names available"), +- VIR_NET_GENERATED_PREFIX); +- return -1; +- } ++ VIR_INFO("marking device in use: '%s'", name); + +- if (virBitmapIsBitSet(bitmap, id)) { +- if (quietFail) { +- VIR_INFO("couldn't reserve name %s%d - already in use", +- VIR_NET_GENERATED_PREFIX, id); +- } else { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("couldn't reserve name %s%d - already in use"), +- VIR_NET_GENERATED_PREFIX, id); +- } +- return -1; +- } ++ idstr = name + len; + +- if (virBitmapSetBit(bitmap, id) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("couldn't mark %s%d as used"), +- VIR_NET_GENERATED_PREFIX, id); +- return -1; ++ if (virStrToLong_ui(idstr, NULL, 10, &id) >= 0) { ++ if (*lastID < (int)id) ++ *lastID = id; + } +- +- VIR_INFO("reserving device %s%d", VIR_NET_GENERATED_PREFIX, id); +- return id; + } + + + /** +- * virNetDevMacVLanReleaseID: +- * @id: id 0 - MACVLAN_MAX_ID+1 to release ++ * virNetDevMacVLanReserveName: ++ * @name: name of an existing macvtap/macvlan device + * +- * Returns 0 for success or -1 for failure. ++ * Set the value of virNetDevMacV(Lan|Tap)LastID to assure that any ++ * new device created with an autogenerated name will use a number ++ * higher than the number in the given device name. ++ * ++ * Returns nothing. + */ +-static int +-virNetDevMacVLanReleaseID(int id, unsigned int flags) ++void ++virNetDevMacVLanReserveName(const char *name) + { +- virBitmapPtr bitmap; +- +- if (virNetDevMacVLanInitialize() < 0) +- return 0; +- +- bitmap = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? +- macvtapIDs : macvlanIDs; +- +- if (id > MACVLAN_MAX_ID) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("can't free name %s%d - out of range 0-%d"), +- VIR_NET_GENERATED_PREFIX, id, MACVLAN_MAX_ID); +- return -1; +- } +- +- if (id < 0) +- return 0; +- +- VIR_INFO("releasing %sdevice %s%d", +- virBitmapIsBitSet(bitmap, id) ? "" : "unreserved", +- VIR_NET_GENERATED_PREFIX, id); +- +- if (virBitmapClearBit(bitmap, id) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("couldn't mark %s%d as unused"), +- VIR_NET_GENERATED_PREFIX, id); +- return -1; +- } +- return 0; ++ virMutexLock(&virNetDevMacVLanCreateMutex); ++ virNetDevMacVLanReserveNameInternal(name); ++ virMutexUnlock(&virNetDevMacVLanCreateMutex); + } + + + /** +- * virNetDevMacVLanReserveName: +- * +- * @name: already-known name of device +- * @quietFail: don't log an error if this name is already in-use ++ * virNetDevMacVLanGenerateName: ++ * @ifname: pointer to pointer to string containing template ++ * @lastID: counter to add to the template to form the name + * +- * Extract the device type and id from a macvtap/macvlan device name +- * and mark the appropriate position as in-use in the appropriate +- * bitmap. ++ * generate a new (currently unused) name for a new macvtap/macvlan ++ * device based on the template string in @ifname - replace %d with ++ * ++(*counter), and keep trying new values until one is found ++ * that doesn't already exist, or we've tried 10000 different ++ * names. Once a usable name is found, replace the template with the ++ * actual name. + * +- * Returns reserved ID# on success, -1 on failure, -2 if the name +- * doesn't fit the auto-pattern (so not reserveable). ++ * Returns 0 on success, -1 on failure. + */ +-int +-virNetDevMacVLanReserveName(const char *name, bool quietFail) ++static int ++virNetDevMacVLanGenerateName(char **ifname, unsigned int flags) + { +- unsigned int id; +- unsigned int flags = 0; +- const char *idstr = NULL; ++ const char *prefix; ++ const char *iftemplate; ++ int *lastID; ++ int id; ++ double maxIDd; ++ int maxID = INT_MAX; ++ int attempts = 0; + +- if (virNetDevMacVLanInitialize() < 0) +- return -1; +- +- if (STRPREFIX(name, VIR_NET_GENERATED_MACVTAP_PREFIX)) { +- idstr = name + strlen(VIR_NET_GENERATED_MACVTAP_PREFIX); +- flags |= VIR_NETDEV_MACVLAN_CREATE_WITH_TAP; +- } else if (STRPREFIX(name, VIR_NET_GENERATED_MACVLAN_PREFIX)) { +- idstr = name + strlen(VIR_NET_GENERATED_MACVLAN_PREFIX); ++ if (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) { ++ prefix = VIR_NET_GENERATED_MACVTAP_PREFIX; ++ iftemplate = VIR_NET_GENERATED_MACVTAP_PREFIX "%d"; ++ lastID = &virNetDevMacVTapLastID; + } else { +- return -2; ++ prefix = VIR_NET_GENERATED_MACVLAN_PREFIX; ++ iftemplate = VIR_NET_GENERATED_MACVLAN_PREFIX "%d"; ++ lastID = &virNetDevMacVLanLastID; + } + +- if (virStrToLong_ui(idstr, NULL, 10, &id) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("couldn't get id value from macvtap device name %s"), +- name); +- return -1; +- } +- return virNetDevMacVLanReserveID(id, flags, quietFail, false); +-} ++ maxIDd = pow(10, IFNAMSIZ - 1 - strlen(prefix)); ++ if (maxIDd <= (double)INT_MAX) ++ maxID = (int)maxIDd; + ++ do { ++ g_autofree char *try = NULL; + +-/** +- * virNetDevMacVLanReleaseName: +- * +- * @name: already-known name of device +- * +- * Extract the device type and id from a macvtap/macvlan device name +- * and mark the appropriate position as in-use in the appropriate +- * bitmap. +- * +- * returns 0 on success, -1 on failure +- */ +-int +-virNetDevMacVLanReleaseName(const char *name) +-{ +- unsigned int id; +- unsigned int flags = 0; +- const char *idstr = NULL; ++ id = ++(*lastID); + +- if (virNetDevMacVLanInitialize() < 0) +- return -1; ++ /* reset before overflow */ ++ if (*lastID == maxID) ++ *lastID = -1; + +- if (STRPREFIX(name, VIR_NET_GENERATED_MACVTAP_PREFIX)) { +- idstr = name + strlen(VIR_NET_GENERATED_MACVTAP_PREFIX); +- flags |= VIR_NETDEV_MACVLAN_CREATE_WITH_TAP; +- } else if (STRPREFIX(name, VIR_NET_GENERATED_MACVLAN_PREFIX)) { +- idstr = name + strlen(VIR_NET_GENERATED_MACVLAN_PREFIX); +- } else { +- return 0; +- } ++ try = g_strdup_printf(iftemplate, id); + +- if (virStrToLong_ui(idstr, NULL, 10, &id) < 0) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("couldn't get id value from macvtap device name %s"), +- name); +- return -1; +- } +- return virNetDevMacVLanReleaseID(id, flags); ++ if (!virNetDevExists(try)) { ++ g_free(*ifname); ++ *ifname = g_steal_pointer(&try); ++ return 0; ++ } ++ } while (++attempts < 10000); ++ ++ virReportError(VIR_ERR_INTERNAL_ERROR, ++ _("no unused %s names available"), ++ *ifname); ++ return -1; + } + + +@@ -321,8 +232,7 @@ virNetDevMacVLanCreate(const char *ifname, + const char *type, + const virMacAddr *macaddress, + const char *srcdev, +- uint32_t macvlan_mode, +- int *retry) ++ uint32_t macvlan_mode) + { + int error = 0; + int ifindex = 0; +@@ -331,7 +241,6 @@ virNetDevMacVLanCreate(const char *ifname, + .mac = macaddress, + }; + +- *retry = 0; + + if (virNetDevGetIndex(srcdev, &ifindex) < 0) + return -1; +@@ -339,17 +248,15 @@ virNetDevMacVLanCreate(const char *ifname, + data.ifindex = &ifindex; + if (virNetlinkNewLink(ifname, type, &data, &error) < 0) { + char macstr[VIR_MAC_STRING_BUFLEN]; +- if (error == -EEXIST) +- *retry = 1; +- else if (error < 0) +- virReportSystemError(-error, +- _("error creating %s interface %s@%s (%s)"), +- type, ifname, srcdev, +- virMacAddrFormat(macaddress, macstr)); + ++ virReportSystemError(-error, ++ _("error creating %s interface %s@%s (%s)"), ++ type, ifname, srcdev, ++ virMacAddrFormat(macaddress, macstr)); + return -1; + } + ++ VIR_INFO("created device: '%s'", ifname); + return 0; + } + +@@ -364,6 +271,7 @@ virNetDevMacVLanCreate(const char *ifname, + */ + int virNetDevMacVLanDelete(const char *ifname) + { ++ VIR_INFO("delete device: '%s'", ifname); + return virNetlinkDelLink(ifname, NULL); + } + +@@ -904,13 +812,8 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested, + unsigned int flags) + { + const char *type = VIR_NET_GENERATED_PREFIX; +- const char *pattern = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? +- VIR_NET_GENERATED_MACVTAP_PATTERN : VIR_NET_GENERATED_MACVLAN_PATTERN; +- int reservedID = -1; +- char ifname[IFNAMSIZ]; +- int retries, do_retry = 0; ++ g_autofree char *ifname = NULL; + uint32_t macvtapMode; +- const char *ifnameCreated = NULL; + int vf = -1; + bool vnet_hdr = flags & VIR_NETDEV_MACVLAN_VNET_HDR; + +@@ -945,6 +848,8 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested, + return -1; + } + ++ virMutexLock(&virNetDevMacVLanCreateMutex); ++ + if (ifnameRequested) { + int rc; + bool isAutoName +@@ -952,97 +857,81 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested, + STRPREFIX(ifnameRequested, VIR_NET_GENERATED_MACVLAN_PREFIX)); + + VIR_INFO("Requested macvtap device name: %s", ifnameRequested); +- virMutexLock(&virNetDevMacVLanCreateMutex); + + if ((rc = virNetDevExists(ifnameRequested)) < 0) { + virMutexUnlock(&virNetDevMacVLanCreateMutex); + return -1; + } ++ + if (rc) { +- if (isAutoName) +- goto create_name; +- virReportSystemError(EEXIST, +- _("Unable to create %s device %s"), +- type, ifnameRequested); +- virMutexUnlock(&virNetDevMacVLanCreateMutex); +- return -1; +- } +- if (isAutoName && +- (reservedID = virNetDevMacVLanReserveName(ifnameRequested, true)) < 0) { +- reservedID = -1; +- goto create_name; +- } ++ /* ifnameRequested is already being used */ + +- if (virNetDevMacVLanCreate(ifnameRequested, type, macaddress, +- linkdev, macvtapMode, &do_retry) < 0) { +- if (isAutoName) { +- virNetDevMacVLanReleaseName(ifnameRequested); +- reservedID = -1; +- goto create_name; ++ if (!isAutoName) { ++ virReportSystemError(EEXIST, ++ _("Unable to create device '%s'"), ++ ifnameRequested); ++ virMutexUnlock(&virNetDevMacVLanCreateMutex); ++ return -1; ++ } ++ } else { ++ ++ /* ifnameRequested is available. try to open it */ ++ ++ virNetDevMacVLanReserveNameInternal(ifnameRequested); ++ ++ if (virNetDevMacVLanCreate(ifnameRequested, type, macaddress, ++ linkdev, macvtapMode) == 0) { ++ ++ /* virNetDevMacVLanCreate() was successful - use this name */ ++ ifname = g_strdup(ifnameRequested); ++ ++ } else if (!isAutoName) { ++ /* coudn't open ifnameRequested, but it wasn't an ++ * autogenerated named, so there is nothing else to ++ * try - fail and return. ++ */ ++ virMutexUnlock(&virNetDevMacVLanCreateMutex); ++ return -1; + } +- virMutexUnlock(&virNetDevMacVLanCreateMutex); +- return -1; + } +- /* virNetDevMacVLanCreate() was successful - use this name */ +- ifnameCreated = ifnameRequested; +- create_name: +- virMutexUnlock(&virNetDevMacVLanCreateMutex); + } + +- retries = MACVLAN_MAX_ID; +- while (!ifnameCreated && retries) { +- virMutexLock(&virNetDevMacVLanCreateMutex); +- reservedID = virNetDevMacVLanReserveID(reservedID, flags, false, true); +- if (reservedID < 0) { ++ if (!ifname) { ++ /* ifnameRequested was NULL, or it was an already in use ++ * autogenerated name, so now we look for an unused ++ * autogenerated name. ++ */ ++ if (virNetDevMacVLanGenerateName(&ifname, flags) < 0 || ++ virNetDevMacVLanCreate(ifname, type, macaddress, ++ linkdev, macvtapMode) < 0) { + virMutexUnlock(&virNetDevMacVLanCreateMutex); + return -1; + } +- g_snprintf(ifname, sizeof(ifname), pattern, reservedID); +- if (virNetDevMacVLanCreate(ifname, type, macaddress, linkdev, +- macvtapMode, &do_retry) < 0) { +- virNetDevMacVLanReleaseID(reservedID, flags); +- virMutexUnlock(&virNetDevMacVLanCreateMutex); +- if (!do_retry) +- return -1; +- VIR_INFO("Device %s wasn't reserved but already existed, skipping", +- ifname); +- retries--; +- continue; +- } +- ifnameCreated = ifname; +- virMutexUnlock(&virNetDevMacVLanCreateMutex); + } + +- if (!ifnameCreated) { +- virReportError(VIR_ERR_INTERNAL_ERROR, +- _("Too many unreserved %s devices in use"), +- type); +- return -1; +- } ++ /* all done creating the device */ ++ virMutexUnlock(&virNetDevMacVLanCreateMutex); + +- if (virNetDevVPortProfileAssociate(ifnameCreated, ++ if (virNetDevVPortProfileAssociate(ifname, + virtPortProfile, + macaddress, + linkdev, + vf, +- vmuuid, vmOp, false) < 0) ++ vmuuid, vmOp, false) < 0) { + goto link_del_exit; ++ } + + if (flags & VIR_NETDEV_MACVLAN_CREATE_IFUP) { +- if (virNetDevSetOnline(ifnameCreated, true) < 0) ++ if (virNetDevSetOnline(ifname, true) < 0) + goto disassociate_exit; + } + + if (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) { +- if (virNetDevMacVLanTapOpen(ifnameCreated, tapfd, tapfdSize) < 0) ++ if (virNetDevMacVLanTapOpen(ifname, tapfd, tapfdSize) < 0) + goto disassociate_exit; + + if (virNetDevMacVLanTapSetup(tapfd, tapfdSize, vnet_hdr) < 0) + goto disassociate_exit; +- +- *ifnameResult = g_strdup(ifnameCreated); +- } else { +- *ifnameResult = g_strdup(ifnameCreated); + } + + if (vmOp == VIR_NETDEV_VPORT_PROFILE_OP_CREATE || +@@ -1051,17 +940,18 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested, + * a saved image) - migration and libvirtd restart are handled + * elsewhere. + */ +- if (virNetDevMacVLanVPortProfileRegisterCallback(ifnameCreated, macaddress, ++ if (virNetDevMacVLanVPortProfileRegisterCallback(ifname, macaddress, + linkdev, vmuuid, + virtPortProfile, + vmOp) < 0) + goto disassociate_exit; + } + ++ *ifnameResult = g_steal_pointer(&ifname); + return 0; + + disassociate_exit: +- ignore_value(virNetDevVPortProfileDisassociate(ifnameCreated, ++ ignore_value(virNetDevVPortProfileDisassociate(ifname, + virtPortProfile, + macaddress, + linkdev, +@@ -1071,9 +961,7 @@ virNetDevMacVLanCreateWithVPortProfile(const char *ifnameRequested, + VIR_FORCE_CLOSE(tapfd[tapfdSize]); + + link_del_exit: +- ignore_value(virNetDevMacVLanDelete(ifnameCreated)); +- virNetDevMacVLanReleaseName(ifnameCreated); +- ++ ignore_value(virNetDevMacVLanDelete(ifname)); + return -1; + } + +@@ -1107,7 +995,6 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname, + ret = -1; + if (virNetDevMacVLanDelete(ifname) < 0) + ret = -1; +- virNetDevMacVLanReleaseName(ifname); + } + + if (mode == VIR_NETDEV_MACVLAN_MODE_PASSTHRU) { +@@ -1182,8 +1069,7 @@ int virNetDevMacVLanCreate(const char *ifname G_GNUC_UNUSED, + const char *type G_GNUC_UNUSED, + const virMacAddr *macaddress G_GNUC_UNUSED, + const char *srcdev G_GNUC_UNUSED, +- uint32_t macvlan_mode G_GNUC_UNUSED, +- int *retry G_GNUC_UNUSED) ++ uint32_t macvlan_mode G_GNUC_UNUSED) + { + virReportSystemError(ENOSYS, "%s", + _("Cannot create macvlan devices on this platform")); +@@ -1272,18 +1158,9 @@ int virNetDevMacVLanVPortProfileRegisterCallback(const char *ifname G_GNUC_UNUSE + return -1; + } + +-int virNetDevMacVLanReleaseName(const char *name G_GNUC_UNUSED) ++void virNetDevMacVLanReserveName(const char *name G_GNUC_UNUSED) + { + virReportSystemError(ENOSYS, "%s", + _("Cannot create macvlan devices on this platform")); +- return -1; +-} +- +-int virNetDevMacVLanReserveName(const char *name G_GNUC_UNUSED, +- bool quietFail G_GNUC_UNUSED) +-{ +- virReportSystemError(ENOSYS, "%s", +- _("Cannot create macvlan devices on this platform")); +- return -1; + } + #endif /* ! WITH_MACVTAP */ +diff --git a/src/util/virnetdevmacvlan.h b/src/util/virnetdevmacvlan.h +index fc1bb018a2..48800a8fcf 100644 +--- a/src/util/virnetdevmacvlan.h ++++ b/src/util/virnetdevmacvlan.h +@@ -54,8 +54,7 @@ typedef enum { + #define VIR_NET_GENERATED_MACVTAP_PREFIX "macvtap" + #define VIR_NET_GENERATED_MACVLAN_PREFIX "macvlan" + +-int virNetDevMacVLanReserveName(const char *name, bool quietfail); +-int virNetDevMacVLanReleaseName(const char *name); ++void virNetDevMacVLanReserveName(const char *name); + + bool virNetDevMacVLanIsMacvtap(const char *ifname) + ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT G_GNUC_NO_INLINE; +@@ -64,8 +63,7 @@ int virNetDevMacVLanCreate(const char *ifname, + const char *type, + const virMacAddr *macaddress, + const char *srcdev, +- uint32_t macvlan_mode, +- int *retry) ++ uint32_t macvlan_mode) + ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) + G_GNUC_WARN_UNUSED_RESULT; + +-- +2.29.2 + diff --git a/SOURCES/libvirt-util-synchronize-with-firewalld-before-we-start-calling-iptables-directly.patch b/SOURCES/libvirt-util-synchronize-with-firewalld-before-we-start-calling-iptables-directly.patch new file mode 100644 index 0000000..63ca58b --- /dev/null +++ b/SOURCES/libvirt-util-synchronize-with-firewalld-before-we-start-calling-iptables-directly.patch @@ -0,0 +1,152 @@ +From dc8cf11686c075166a3029e974a6caeefe521d75 Mon Sep 17 00:00:00 2001 +Message-Id: <dc8cf11686c075166a3029e974a6caeefe521d75@dist-git> +From: Laine Stump <laine@redhat.com> +Date: Fri, 15 Jan 2021 22:51:50 -0500 +Subject: [PATCH] util: synchronize with firewalld before we start calling + iptables directly + +When it is starting up, firewalld will delete all existing iptables +rules and chains before adding its own rules. If libvirtd were to try +to directly add iptables rules during the time before firewalld has +finished initializing, firewalld would end up deleting the rules that +libvirtd has just added. + +Currently this isn't a problem, since libvirtd only adds iptables +rules via the firewalld "passthrough command" API, and so firewalld is +able to properly serialize everything. However, we will soon be +changing libvirtd to add its iptables and ebtables rules by directly +calling iptables/ebtables rather than via firewalld, thus removing the +serialization of libvirtd adding rules vs. firewalld deleting rules. + +This will especially apparent (if we don't fix it in advance, as this +patch does) when libvirtd is responding to the dbus NameOwnerChanged +event, which is used to learn when firewalld has been restarted. In +that case, dbus sends the event before firewalld has been able to +complete its initialization, so when libvirt responds to the event by +adding back its iptables rules (with direct calls to +/usr/bin/iptables), some of those rules are added before firewalld has +a chance to do its "remove everything" startup protocol. The usual +result of this is that libvirt will successfully add its private +chains (e.g. LIBVIRT_INP, etc), but then fail when it tries to add a +rule jumping to one of those chains (because in the interim, firewalld +has deleted the new chains). + +The solution is for libvirt to preface it's direct calling to iptables +with a iptables command sent via firewalld's passthrough command +API. Since commands sent to firewalld are completed synchronously, and +since firewalld won't service them until it has completed its own +initialization, this will assure that by the time libvirt starts +calling iptables to add rules, that firewalld will not be following up +by deleting any of those rules. + +To minimize the amount of extra overhead, we request the simplest +iptables command possible: "iptables -V" (and aside from logging a +debug message, we ignore the result, for good measure). + +(This patch is being done *before* the patch that switches to calling +iptables directly, so that everything will function properly with any +fractional part of the series applied). + +https://bugzilla.redhat.com/1607929 + +Signed-off-by: Laine Stump <laine@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit 070690538a1ed301b004c542d94b13ee9bffc9d6) + +Conflicts: src/util/viriptables.c: + one line of code in context moved during g_autoptr conversion. +Signed-off-by: Laine Stump <laine@redhat.com> +Message-Id: <20210116035151.1066734-8-laine@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/libvirt_private.syms | 1 + + src/util/virfirewall.c | 30 ++++++++++++++++++++++++++++++ + src/util/virfirewall.h | 2 ++ + src/util/viriptables.c | 7 +++++++ + 4 files changed, 40 insertions(+) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index edc53ce899..9d87e2a27b 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2080,6 +2080,7 @@ virFileCacheSetPriv; + # util/virfirewall.h + virFirewallAddRuleFull; + virFirewallApply; ++virFirewallBackendSynchronize; + virFirewallFree; + virFirewallNew; + virFirewallRemoveRule; +diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c +index 520d515c11..66d20d3f17 100644 +--- a/src/util/virfirewall.c ++++ b/src/util/virfirewall.c +@@ -653,6 +653,36 @@ virFirewallApplyRuleFirewallD(virFirewallRulePtr rule, + return virFirewallDApplyRule(rule->layer, rule->args, rule->argsLen, ignoreErrors, output); + } + ++ ++void ++virFirewallBackendSynchronize(void) ++{ ++ const char *arg = "-V"; ++ g_autofree char *output = NULL; ++ ++ switch (currentBackend) { ++ case VIR_FIREWALL_BACKEND_DIRECT: ++ /* nobody to synchronize with */ ++ break; ++ case VIR_FIREWALL_BACKEND_FIREWALLD: ++ /* Send a simple rule via firewalld's passthrough iptables ++ * command so that we'll be sure firewalld has fully ++ * initialized and caught up with its internal queue of ++ * iptables commands. Waiting for this will prevent our own ++ * directly-executed iptables commands from being run while ++ * firewalld is still initializing. ++ */ ++ ignore_value(virFirewallDApplyRule(VIR_FIREWALL_LAYER_IPV4, ++ (char **)&arg, 1, true, &output)); ++ VIR_DEBUG("Result of 'iptables -V' via firewalld: %s", NULLSTR(output)); ++ break; ++ case VIR_FIREWALL_BACKEND_AUTOMATIC: ++ case VIR_FIREWALL_BACKEND_LAST: ++ break; ++ } ++} ++ ++ + static int + virFirewallApplyRule(virFirewallPtr firewall, + virFirewallRulePtr rule, +diff --git a/src/util/virfirewall.h b/src/util/virfirewall.h +index fda3cdec01..3db0864380 100644 +--- a/src/util/virfirewall.h ++++ b/src/util/virfirewall.h +@@ -111,4 +111,6 @@ void virFirewallStartRollback(virFirewallPtr firewall, + + int virFirewallApply(virFirewallPtr firewall); + ++void virFirewallBackendSynchronize(void); ++ + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virFirewall, virFirewallFree); +diff --git a/src/util/viriptables.c b/src/util/viriptables.c +index 6b3a025880..41544b7f36 100644 +--- a/src/util/viriptables.c ++++ b/src/util/viriptables.c +@@ -154,6 +154,13 @@ iptablesSetupPrivateChains(virFirewallLayer layer) + + fw = virFirewallNew(); + ++ /* When the backend is firewalld, we need to make sure that ++ * firewalld has been fully started and completed its ++ * initialization, otherwise firewalld might delete our rules soon ++ * after we add them! ++ */ ++ virFirewallBackendSynchronize(); ++ + virFirewallStartTransaction(fw, 0); + + for (i = 0; i < G_N_ELEMENTS(data); i++) +-- +2.30.0 + diff --git a/SOURCES/libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-by-default.patch b/SOURCES/libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-by-default.patch new file mode 100644 index 0000000..6446cf4 --- /dev/null +++ b/SOURCES/libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-by-default.patch @@ -0,0 +1,225 @@ +From d7703d11a44505d1a17001d8cfd36bf74d20b710 Mon Sep 17 00:00:00 2001 +Message-Id: <d7703d11a44505d1a17001d8cfd36bf74d20b710@dist-git> +From: Laine Stump <laine@redhat.com> +Date: Fri, 15 Jan 2021 22:51:46 -0500 +Subject: [PATCH] util/tests: enable locking on iptables/ebtables commandlines + by default + +iptables and ip6tables have had a "-w" commandline option to grab a +systemwide lock that prevents two iptables invocations from modifying +the iptables chains since 2013 (upstream commit 93587a04 in +iptables-1.4.20). Similarly, ebtables has had a "--concurrent" +commandline option for the same purpose since 2011 (in the upstream +ebtables commit f9b4bcb93, which was present in ebtables-2.0.10.4). + +Libvirt added code to conditionally use the commandline option for +iptables/ip6tables in upstream commit ba95426d6f (libvirt-1.2.0, +November 2013), and for ebtables in upstream commit dc33e6e4a5 +(libvirt-1.2.11, November 2014) (the latter actually *re*-added the +locking for iptables/ip6tables, as it had accidentally been removed +during a refactor of firewall code in the interim). + +I say "conditionally" because a check was made during firewall module +initialization that tried executing a test command with the +-w/--concurrent option, and only continued using it for actual +commands if that test command completed successfully. At the time the +code was added this was a reasonable thing to do, as it had been less +than a year since introduction of -w to iptables, so many distros +supported by libvirt were still using iptables (and possibly even +ebtables) versions too old to have the new commandline options. + +It is now 2020, and as far as I can discern from repology.org (and +manually examining a RHEL7.9 system), every version of every distro +that is supported by libvirt now uses new enough versions of both +iptables and ebtables that they all have support for -w/--concurrent. +That means we can finally remove the conditional code and simply +always use them. + +https://bugzilla.redhat.com/1607929 + +Signed-off-by: Laine Stump <laine@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit 0a867cd895f06134d24eb27070285bb4b50c088f) +Message-Id: <20210116035151.1066734-4-laine@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/libvirt_private.syms | 1 - + src/util/virfirewall.c | 64 ++------------------------------ + src/util/virfirewall.h | 2 - + tests/networkxml2firewalltest.c | 2 - + tests/nwfilterebiptablestest.c | 2 - + tests/nwfilterxml2firewalltest.c | 2 - + tests/virfirewalltest.c | 2 - + 7 files changed, 3 insertions(+), 72 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index d6598c2514..edc53ce899 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2089,7 +2089,6 @@ virFirewallRuleAddArgList; + virFirewallRuleAddArgSet; + virFirewallRuleGetArgCount; + virFirewallSetBackend; +-virFirewallSetLockOverride; + virFirewallStartRollback; + virFirewallStartTransaction; + +diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c +index c2de2bccae..2e3b02402e 100644 +--- a/src/util/virfirewall.c ++++ b/src/util/virfirewall.c +@@ -97,59 +97,6 @@ virFirewallOnceInit(void) + + VIR_ONCE_GLOBAL_INIT(virFirewall); + +-static bool iptablesUseLock; +-static bool ip6tablesUseLock; +-static bool ebtablesUseLock; +-static bool lockOverride; /* true to avoid lock probes */ +- +-void +-virFirewallSetLockOverride(bool avoid) +-{ +- lockOverride = avoid; +- if (avoid) { +- /* add the lock option to all commands */ +- iptablesUseLock = true; +- ip6tablesUseLock = true; +- ebtablesUseLock = true; +- } +-} +- +-static void +-virFirewallCheckUpdateLock(bool *lockflag, +- const char *const*args) +-{ +- int status; /* Ignore failed commands without logging them */ +- g_autoptr(virCommand) cmd = virCommandNewArgs(args); +- if (virCommandRun(cmd, &status) < 0 || status) { +- VIR_INFO("locking not supported by %s", args[0]); +- } else { +- VIR_INFO("using locking for %s", args[0]); +- *lockflag = true; +- } +-} +- +-static void +-virFirewallCheckUpdateLocking(void) +-{ +- const char *iptablesArgs[] = { +- IPTABLES_PATH, "-w", "-L", "-n", NULL, +- }; +- const char *ip6tablesArgs[] = { +- IP6TABLES_PATH, "-w", "-L", "-n", NULL, +- }; +- const char *ebtablesArgs[] = { +- EBTABLES_PATH, "--concurrent", "-L", NULL, +- }; +- if (lockOverride) +- return; +- virFirewallCheckUpdateLock(&iptablesUseLock, +- iptablesArgs); +- virFirewallCheckUpdateLock(&ip6tablesUseLock, +- ip6tablesArgs); +- virFirewallCheckUpdateLock(&ebtablesUseLock, +- ebtablesArgs); +-} +- + static int + virFirewallValidateBackend(virFirewallBackend backend) + { +@@ -197,8 +144,6 @@ virFirewallValidateBackend(virFirewallBackend backend) + + currentBackend = backend; + +- virFirewallCheckUpdateLocking(); +- + return 0; + } + +@@ -363,16 +308,13 @@ virFirewallAddRuleFullV(virFirewallPtr firewall, + + switch (rule->layer) { + case VIR_FIREWALL_LAYER_ETHERNET: +- if (ebtablesUseLock) +- ADD_ARG(rule, "--concurrent"); ++ ADD_ARG(rule, "--concurrent"); + break; + case VIR_FIREWALL_LAYER_IPV4: +- if (iptablesUseLock) +- ADD_ARG(rule, "-w"); ++ ADD_ARG(rule, "-w"); + break; + case VIR_FIREWALL_LAYER_IPV6: +- if (ip6tablesUseLock) +- ADD_ARG(rule, "-w"); ++ ADD_ARG(rule, "-w"); + break; + case VIR_FIREWALL_LAYER_LAST: + break; +diff --git a/src/util/virfirewall.h b/src/util/virfirewall.h +index 6148f46827..fda3cdec01 100644 +--- a/src/util/virfirewall.h ++++ b/src/util/virfirewall.h +@@ -111,6 +111,4 @@ void virFirewallStartRollback(virFirewallPtr firewall, + + int virFirewallApply(virFirewallPtr firewall); + +-void virFirewallSetLockOverride(bool avoid); +- + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virFirewall, virFirewallFree); +diff --git a/tests/networkxml2firewalltest.c b/tests/networkxml2firewalltest.c +index 0ad5e2303b..886b268319 100644 +--- a/tests/networkxml2firewalltest.c ++++ b/tests/networkxml2firewalltest.c +@@ -152,8 +152,6 @@ mymain(void) + ret = -1; \ + } while (0) + +- virFirewallSetLockOverride(true); +- + if (virFirewallSetBackend(VIR_FIREWALL_BACKEND_DIRECT) < 0) { + if (!hasNetfilterTools()) { + fprintf(stderr, "iptables/ip6tables/ebtables tools not present"); +diff --git a/tests/nwfilterebiptablestest.c b/tests/nwfilterebiptablestest.c +index e70f0e2400..adce7430a9 100644 +--- a/tests/nwfilterebiptablestest.c ++++ b/tests/nwfilterebiptablestest.c +@@ -510,8 +510,6 @@ mymain(void) + { + int ret = 0; + +- virFirewallSetLockOverride(true); +- + if (virFirewallSetBackend(VIR_FIREWALL_BACKEND_DIRECT) < 0) { + if (!hasNetfilterTools()) { + fprintf(stderr, "iptables/ip6tables/ebtables tools not present"); +diff --git a/tests/nwfilterxml2firewalltest.c b/tests/nwfilterxml2firewalltest.c +index c97f83b24a..73f7991a96 100644 +--- a/tests/nwfilterxml2firewalltest.c ++++ b/tests/nwfilterxml2firewalltest.c +@@ -459,8 +459,6 @@ mymain(void) + ret = -1; \ + } while (0) + +- virFirewallSetLockOverride(true); +- + if (virFirewallSetBackend(VIR_FIREWALL_BACKEND_DIRECT) < 0) { + if (!hasNetfilterTools()) { + fprintf(stderr, "iptables/ip6tables/ebtables tools not present"); +diff --git a/tests/virfirewalltest.c b/tests/virfirewalltest.c +index 195163a985..1ec768d302 100644 +--- a/tests/virfirewalltest.c ++++ b/tests/virfirewalltest.c +@@ -1141,8 +1141,6 @@ mymain(void) + RUN_TEST_DIRECT(name, method) + # endif /* ! WITH_DBUS */ + +- virFirewallSetLockOverride(true); +- + RUN_TEST("single group", testFirewallSingleGroup); + RUN_TEST("remove rule", testFirewallRemoveRule); + RUN_TEST("many groups", testFirewallManyGroups); +-- +2.30.0 + diff --git a/SOURCES/libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-in-unit-tests.patch b/SOURCES/libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-in-unit-tests.patch new file mode 100644 index 0000000..6230734 --- /dev/null +++ b/SOURCES/libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-in-unit-tests.patch @@ -0,0 +1,6497 @@ +From 4dcb98488fe7049c914a9e2bd82d2fcae834bba5 Mon Sep 17 00:00:00 2001 +Message-Id: <4dcb98488fe7049c914a9e2bd82d2fcae834bba5@dist-git> +From: Laine Stump <laine@redhat.com> +Date: Fri, 15 Jan 2021 22:51:45 -0500 +Subject: [PATCH] util/tests: enable locking on iptables/ebtables commandlines + in unit tests + +All the unit tests that use iptables/ip6tables/ebtables have been +written to omit the locking/exclusive use primitive on the generated +commandlines. Even though none of the tests actually execute those +commands (and so it doesn't matter for purposes of the test whether or +not the commands support these options), it still made sense when some +systems had these locking options and some didn't. + +We are now at a point where every supported Linux distro has supported +the locking options on these commands for quite a long time, and are +going to make their use non-optional. As a first step, this patch uses +the virFirewallSetLockOverride() function, which is called at the +beginning of all firewall-related tests, to set all the bools +controlling whether or not the locking options are used to true. This +means that all the test cases must be updated to include the proper +locking option in their commandlines. + +The change to make actual execs of the commands unconditionally use +the locking option will be in an upcoming patch - this one affects +only the unit tests. + +https://bugzilla.redhat.com/1607929 + +Signed-off-by: Laine Stump <laine@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit e66451f685e29ffe4be5a060ef64b19961ad4bb5) + +Conflicts: + tests/networkxml2firewalldata/nat-ipv6-masquerade-linux.args: + exists only upstream + + tests/virfirewalltest.c: + minor merge conflict due to glib conversion upstream. + +Signed-off-by: Laine Stump <laine@redhat.com> +Message-Id: <20210116035151.1066734-3-laine@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/util/virfirewall.c | 6 + + tests/networkxml2firewalldata/base.args | 34 ++ + .../nat-default-linux.args | 19 + + .../nat-ipv6-linux.args | 30 ++ + .../nat-many-ips-linux.args | 33 ++ + .../nat-no-dhcp-linux.args | 29 ++ + .../nat-tftp-linux.args | 21 + + .../route-default-linux.args | 14 + + tests/nwfilterebiptablestest.c | 464 +++++++++--------- + .../ah-ipv6-linux.args | 9 + + tests/nwfilterxml2firewalldata/ah-linux.args | 9 + + .../all-ipv6-linux.args | 9 + + tests/nwfilterxml2firewalldata/all-linux.args | 9 + + tests/nwfilterxml2firewalldata/arp-linux.args | 5 + + .../comment-linux.args | 19 + + .../conntrack-linux.args | 7 + + .../esp-ipv6-linux.args | 9 + + tests/nwfilterxml2firewalldata/esp-linux.args | 9 + + .../example-1-linux.args | 12 + + .../example-2-linux.args | 10 + + .../hex-data-linux.args | 10 + + .../icmp-direction-linux.args | 6 + + .../icmp-direction2-linux.args | 6 + + .../icmp-direction3-linux.args | 6 + + .../nwfilterxml2firewalldata/icmp-linux.args | 3 + + .../icmpv6-linux.args | 4 + + .../nwfilterxml2firewalldata/igmp-linux.args | 9 + + tests/nwfilterxml2firewalldata/ip-linux.args | 3 + + .../nwfilterxml2firewalldata/ipset-linux.args | 18 + + .../ipt-no-macspoof-linux.args | 2 + + .../nwfilterxml2firewalldata/ipv6-linux.args | 15 + + .../nwfilterxml2firewalldata/iter1-linux.args | 9 + + .../nwfilterxml2firewalldata/iter2-linux.args | 171 +++++++ + .../nwfilterxml2firewalldata/iter3-linux.args | 15 + + tests/nwfilterxml2firewalldata/mac-linux.args | 4 + + .../nwfilterxml2firewalldata/rarp-linux.args | 6 + + .../sctp-ipv6-linux.args | 9 + + .../nwfilterxml2firewalldata/sctp-linux.args | 9 + + tests/nwfilterxml2firewalldata/stp-linux.args | 11 + + .../target-linux.args | 33 ++ + .../target2-linux.args | 12 + + .../tcp-ipv6-linux.args | 9 + + tests/nwfilterxml2firewalldata/tcp-linux.args | 13 + + .../udp-ipv6-linux.args | 9 + + tests/nwfilterxml2firewalldata/udp-linux.args | 9 + + .../udplite-ipv6-linux.args | 9 + + .../udplite-linux.args | 9 + + .../nwfilterxml2firewalldata/vlan-linux.args | 7 + + tests/nwfilterxml2firewalltest.c | 144 +++--- + tests/virfirewalltest.c | 112 +++-- + 50 files changed, 1081 insertions(+), 358 deletions(-) + +diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c +index ee72b579e4..c2de2bccae 100644 +--- a/src/util/virfirewall.c ++++ b/src/util/virfirewall.c +@@ -106,6 +106,12 @@ void + virFirewallSetLockOverride(bool avoid) + { + lockOverride = avoid; ++ if (avoid) { ++ /* add the lock option to all commands */ ++ iptablesUseLock = true; ++ ip6tablesUseLock = true; ++ ebtablesUseLock = true; ++ } + } + + static void +diff --git a/tests/networkxml2firewalldata/base.args b/tests/networkxml2firewalldata/base.args +index 0e71bf3a64..056ee12758 100644 +--- a/tests/networkxml2firewalldata/base.args ++++ b/tests/networkxml2firewalldata/base.args +@@ -1,116 +1,150 @@ + iptables \ ++-w \ + --table filter \ + --list-rules + iptables \ ++-w \ + --table nat \ + --list-rules + iptables \ ++-w \ + --table mangle \ + --list-rules + iptables \ ++-w \ + --table filter \ + --new-chain LIBVIRT_INP + iptables \ ++-w \ + --table filter \ + --insert INPUT \ + --jump LIBVIRT_INP + iptables \ ++-w \ + --table filter \ + --new-chain LIBVIRT_OUT + iptables \ ++-w \ + --table filter \ + --insert OUTPUT \ + --jump LIBVIRT_OUT + iptables \ ++-w \ + --table filter \ + --new-chain LIBVIRT_FWO + iptables \ ++-w \ + --table filter \ + --insert FORWARD \ + --jump LIBVIRT_FWO + iptables \ ++-w \ + --table filter \ + --new-chain LIBVIRT_FWI + iptables \ ++-w \ + --table filter \ + --insert FORWARD \ + --jump LIBVIRT_FWI + iptables \ ++-w \ + --table filter \ + --new-chain LIBVIRT_FWX + iptables \ ++-w \ + --table filter \ + --insert FORWARD \ + --jump LIBVIRT_FWX + iptables \ ++-w \ + --table nat \ + --new-chain LIBVIRT_PRT + iptables \ ++-w \ + --table nat \ + --insert POSTROUTING \ + --jump LIBVIRT_PRT + iptables \ ++-w \ + --table mangle \ + --new-chain LIBVIRT_PRT + iptables \ ++-w \ + --table mangle \ + --insert POSTROUTING \ + --jump LIBVIRT_PRT + ip6tables \ ++-w \ + --table filter \ + --list-rules + ip6tables \ ++-w \ + --table nat \ + --list-rules + ip6tables \ ++-w \ + --table mangle \ + --list-rules + ip6tables \ ++-w \ + --table filter \ + --new-chain LIBVIRT_INP + ip6tables \ ++-w \ + --table filter \ + --insert INPUT \ + --jump LIBVIRT_INP + ip6tables \ ++-w \ + --table filter \ + --new-chain LIBVIRT_OUT + ip6tables \ ++-w \ + --table filter \ + --insert OUTPUT \ + --jump LIBVIRT_OUT + ip6tables \ ++-w \ + --table filter \ + --new-chain LIBVIRT_FWO + ip6tables \ ++-w \ + --table filter \ + --insert FORWARD \ + --jump LIBVIRT_FWO + ip6tables \ ++-w \ + --table filter \ + --new-chain LIBVIRT_FWI + ip6tables \ ++-w \ + --table filter \ + --insert FORWARD \ + --jump LIBVIRT_FWI + ip6tables \ ++-w \ + --table filter \ + --new-chain LIBVIRT_FWX + ip6tables \ ++-w \ + --table filter \ + --insert FORWARD \ + --jump LIBVIRT_FWX + ip6tables \ ++-w \ + --table nat \ + --new-chain LIBVIRT_PRT + ip6tables \ ++-w \ + --table nat \ + --insert POSTROUTING \ + --jump LIBVIRT_PRT + ip6tables \ ++-w \ + --table mangle \ + --new-chain LIBVIRT_PRT + ip6tables \ ++-w \ + --table mangle \ + --insert POSTROUTING \ + --jump LIBVIRT_PRT +diff --git a/tests/networkxml2firewalldata/nat-default-linux.args b/tests/networkxml2firewalldata/nat-default-linux.args +index ab18f30bd0..3cfa61333c 100644 +--- a/tests/networkxml2firewalldata/nat-default-linux.args ++++ b/tests/networkxml2firewalldata/nat-default-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -6,6 +7,7 @@ iptables \ + --destination-port 67 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -13,6 +15,7 @@ iptables \ + --destination-port 67 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -20,6 +23,7 @@ iptables \ + --destination-port 68 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -27,6 +31,7 @@ iptables \ + --destination-port 68 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -34,6 +39,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -41,6 +47,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -48,6 +55,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -55,28 +63,33 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --in-interface virbr0 \ + --jump REJECT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --out-interface virbr0 \ + --jump REJECT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWX \ + --in-interface virbr0 \ + --out-interface virbr0 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --source 192.168.122.0/24 \ + --in-interface virbr0 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --destination 192.168.122.0/24 \ +@@ -85,12 +98,14 @@ iptables \ + --ctstate ESTABLISHED,RELATED \ + --jump ACCEPT + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 '!' \ + --destination 192.168.122.0/24 \ + --jump MASQUERADE + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ +@@ -99,6 +114,7 @@ iptables \ + --jump MASQUERADE \ + --to-ports 1024-65535 + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ +@@ -107,18 +123,21 @@ iptables \ + --jump MASQUERADE \ + --to-ports 1024-65535 + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ + --destination 255.255.255.255/32 \ + --jump RETURN + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ + --destination 224.0.0.0/24 \ + --jump RETURN + iptables \ ++-w \ + --table mangle \ + --insert LIBVIRT_PRT \ + --out-interface virbr0 \ +diff --git a/tests/networkxml2firewalldata/nat-ipv6-linux.args b/tests/networkxml2firewalldata/nat-ipv6-linux.args +index 05d9ee33ca..ce295cbc6d 100644 +--- a/tests/networkxml2firewalldata/nat-ipv6-linux.args ++++ b/tests/networkxml2firewalldata/nat-ipv6-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -6,6 +7,7 @@ iptables \ + --destination-port 67 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -13,6 +15,7 @@ iptables \ + --destination-port 67 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -20,6 +23,7 @@ iptables \ + --destination-port 68 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -27,6 +31,7 @@ iptables \ + --destination-port 68 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -34,6 +39,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -41,6 +47,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -48,6 +55,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -55,38 +63,45 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --in-interface virbr0 \ + --jump REJECT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --out-interface virbr0 \ + --jump REJECT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWX \ + --in-interface virbr0 \ + --out-interface virbr0 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --in-interface virbr0 \ + --jump REJECT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --out-interface virbr0 \ + --jump REJECT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWX \ + --in-interface virbr0 \ + --out-interface virbr0 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -94,6 +109,7 @@ ip6tables \ + --destination-port 53 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -101,6 +117,7 @@ ip6tables \ + --destination-port 53 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -108,6 +125,7 @@ ip6tables \ + --destination-port 53 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -115,6 +133,7 @@ ip6tables \ + --destination-port 53 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -122,6 +141,7 @@ ip6tables \ + --destination-port 547 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -129,12 +149,14 @@ ip6tables \ + --destination-port 546 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --source 192.168.122.0/24 \ + --in-interface virbr0 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --destination 192.168.122.0/24 \ +@@ -143,12 +165,14 @@ iptables \ + --ctstate ESTABLISHED,RELATED \ + --jump ACCEPT + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 '!' \ + --destination 192.168.122.0/24 \ + --jump MASQUERADE + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ +@@ -157,6 +181,7 @@ iptables \ + --jump MASQUERADE \ + --to-ports 1024-65535 + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ +@@ -165,30 +190,35 @@ iptables \ + --jump MASQUERADE \ + --to-ports 1024-65535 + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ + --destination 255.255.255.255/32 \ + --jump RETURN + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ + --destination 224.0.0.0/24 \ + --jump RETURN + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --source 2001:db8:ca2:2::/64 \ + --in-interface virbr0 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --destination 2001:db8:ca2:2::/64 \ + --out-interface virbr0 \ + --jump ACCEPT + iptables \ ++-w \ + --table mangle \ + --insert LIBVIRT_PRT \ + --out-interface virbr0 \ +diff --git a/tests/networkxml2firewalldata/nat-many-ips-linux.args b/tests/networkxml2firewalldata/nat-many-ips-linux.args +index 82e1380f51..ba7f234b82 100644 +--- a/tests/networkxml2firewalldata/nat-many-ips-linux.args ++++ b/tests/networkxml2firewalldata/nat-many-ips-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -6,6 +7,7 @@ iptables \ + --destination-port 67 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -13,6 +15,7 @@ iptables \ + --destination-port 67 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -20,6 +23,7 @@ iptables \ + --destination-port 68 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -27,6 +31,7 @@ iptables \ + --destination-port 68 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -34,6 +39,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -41,6 +47,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -48,6 +55,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -55,28 +63,33 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --in-interface virbr0 \ + --jump REJECT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --out-interface virbr0 \ + --jump REJECT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWX \ + --in-interface virbr0 \ + --out-interface virbr0 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --source 192.168.122.0/24 \ + --in-interface virbr0 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --destination 192.168.122.0/24 \ +@@ -85,12 +98,14 @@ iptables \ + --ctstate ESTABLISHED,RELATED \ + --jump ACCEPT + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 '!' \ + --destination 192.168.122.0/24 \ + --jump MASQUERADE + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ +@@ -99,6 +114,7 @@ iptables \ + --jump MASQUERADE \ + --to-ports 1024-65535 + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ +@@ -107,24 +123,28 @@ iptables \ + --jump MASQUERADE \ + --to-ports 1024-65535 + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ + --destination 255.255.255.255/32 \ + --jump RETURN + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ + --destination 224.0.0.0/24 \ + --jump RETURN + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --source 192.168.128.0/24 \ + --in-interface virbr0 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --destination 192.168.128.0/24 \ +@@ -133,12 +153,14 @@ iptables \ + --ctstate ESTABLISHED,RELATED \ + --jump ACCEPT + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.128.0/24 '!' \ + --destination 192.168.128.0/24 \ + --jump MASQUERADE + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.128.0/24 \ +@@ -147,6 +169,7 @@ iptables \ + --jump MASQUERADE \ + --to-ports 1024-65535 + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.128.0/24 \ +@@ -155,24 +178,28 @@ iptables \ + --jump MASQUERADE \ + --to-ports 1024-65535 + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.128.0/24 \ + --destination 255.255.255.255/32 \ + --jump RETURN + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.128.0/24 \ + --destination 224.0.0.0/24 \ + --jump RETURN + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --source 192.168.150.0/24 \ + --in-interface virbr0 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --destination 192.168.150.0/24 \ +@@ -181,12 +208,14 @@ iptables \ + --ctstate ESTABLISHED,RELATED \ + --jump ACCEPT + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.150.0/24 '!' \ + --destination 192.168.150.0/24 \ + --jump MASQUERADE + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.150.0/24 \ +@@ -195,6 +224,7 @@ iptables \ + --jump MASQUERADE \ + --to-ports 1024-65535 + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.150.0/24 \ +@@ -203,18 +233,21 @@ iptables \ + --jump MASQUERADE \ + --to-ports 1024-65535 + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.150.0/24 \ + --destination 255.255.255.255/32 \ + --jump RETURN + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.150.0/24 \ + --destination 224.0.0.0/24 \ + --jump RETURN + iptables \ ++-w \ + --table mangle \ + --insert LIBVIRT_PRT \ + --out-interface virbr0 \ +diff --git a/tests/networkxml2firewalldata/nat-no-dhcp-linux.args b/tests/networkxml2firewalldata/nat-no-dhcp-linux.args +index 8954cc5473..1e5aa05231 100644 +--- a/tests/networkxml2firewalldata/nat-no-dhcp-linux.args ++++ b/tests/networkxml2firewalldata/nat-no-dhcp-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -6,6 +7,7 @@ iptables \ + --destination-port 67 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -13,6 +15,7 @@ iptables \ + --destination-port 67 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -20,6 +23,7 @@ iptables \ + --destination-port 68 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -27,6 +31,7 @@ iptables \ + --destination-port 68 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -34,6 +39,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -41,6 +47,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -48,6 +55,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -55,38 +63,45 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --in-interface virbr0 \ + --jump REJECT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --out-interface virbr0 \ + --jump REJECT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWX \ + --in-interface virbr0 \ + --out-interface virbr0 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --in-interface virbr0 \ + --jump REJECT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --out-interface virbr0 \ + --jump REJECT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWX \ + --in-interface virbr0 \ + --out-interface virbr0 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -94,6 +109,7 @@ ip6tables \ + --destination-port 53 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -101,6 +117,7 @@ ip6tables \ + --destination-port 53 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -108,6 +125,7 @@ ip6tables \ + --destination-port 53 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -115,6 +133,7 @@ ip6tables \ + --destination-port 53 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -122,6 +141,7 @@ ip6tables \ + --destination-port 547 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -129,12 +149,14 @@ ip6tables \ + --destination-port 546 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --source 192.168.122.0/24 \ + --in-interface virbr0 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --destination 192.168.122.0/24 \ +@@ -143,12 +165,14 @@ iptables \ + --ctstate ESTABLISHED,RELATED \ + --jump ACCEPT + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 '!' \ + --destination 192.168.122.0/24 \ + --jump MASQUERADE + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ +@@ -157,6 +181,7 @@ iptables \ + --jump MASQUERADE \ + --to-ports 1024-65535 + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ +@@ -165,24 +190,28 @@ iptables \ + --jump MASQUERADE \ + --to-ports 1024-65535 + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ + --destination 255.255.255.255/32 \ + --jump RETURN + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ + --destination 224.0.0.0/24 \ + --jump RETURN + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --source 2001:db8:ca2:2::/64 \ + --in-interface virbr0 \ + --jump ACCEPT + ip6tables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --destination 2001:db8:ca2:2::/64 \ +diff --git a/tests/networkxml2firewalldata/nat-tftp-linux.args b/tests/networkxml2firewalldata/nat-tftp-linux.args +index 88e9929b62..565fff737c 100644 +--- a/tests/networkxml2firewalldata/nat-tftp-linux.args ++++ b/tests/networkxml2firewalldata/nat-tftp-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -6,6 +7,7 @@ iptables \ + --destination-port 67 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -13,6 +15,7 @@ iptables \ + --destination-port 67 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -20,6 +23,7 @@ iptables \ + --destination-port 68 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -27,6 +31,7 @@ iptables \ + --destination-port 68 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -34,6 +39,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -41,6 +47,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -48,6 +55,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -55,6 +63,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -62,6 +71,7 @@ iptables \ + --destination-port 69 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -69,28 +79,33 @@ iptables \ + --destination-port 69 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --in-interface virbr0 \ + --jump REJECT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --out-interface virbr0 \ + --jump REJECT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWX \ + --in-interface virbr0 \ + --out-interface virbr0 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --source 192.168.122.0/24 \ + --in-interface virbr0 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --destination 192.168.122.0/24 \ +@@ -99,12 +114,14 @@ iptables \ + --ctstate ESTABLISHED,RELATED \ + --jump ACCEPT + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 '!' \ + --destination 192.168.122.0/24 \ + --jump MASQUERADE + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ +@@ -113,6 +130,7 @@ iptables \ + --jump MASQUERADE \ + --to-ports 1024-65535 + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ +@@ -121,18 +139,21 @@ iptables \ + --jump MASQUERADE \ + --to-ports 1024-65535 + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ + --destination 255.255.255.255/32 \ + --jump RETURN + iptables \ ++-w \ + --table nat \ + --insert LIBVIRT_PRT \ + --source 192.168.122.0/24 \ + --destination 224.0.0.0/24 \ + --jump RETURN + iptables \ ++-w \ + --table mangle \ + --insert LIBVIRT_PRT \ + --out-interface virbr0 \ +diff --git a/tests/networkxml2firewalldata/route-default-linux.args b/tests/networkxml2firewalldata/route-default-linux.args +index c427d9602d..a7b969c077 100644 +--- a/tests/networkxml2firewalldata/route-default-linux.args ++++ b/tests/networkxml2firewalldata/route-default-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -6,6 +7,7 @@ iptables \ + --destination-port 67 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -13,6 +15,7 @@ iptables \ + --destination-port 67 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -20,6 +23,7 @@ iptables \ + --destination-port 68 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -27,6 +31,7 @@ iptables \ + --destination-port 68 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -34,6 +39,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_INP \ + --in-interface virbr0 \ +@@ -41,6 +47,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -48,6 +55,7 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_OUT \ + --out-interface virbr0 \ +@@ -55,34 +63,40 @@ iptables \ + --destination-port 53 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --in-interface virbr0 \ + --jump REJECT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --out-interface virbr0 \ + --jump REJECT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWX \ + --in-interface virbr0 \ + --out-interface virbr0 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWO \ + --source 192.168.122.0/24 \ + --in-interface virbr0 \ + --jump ACCEPT + iptables \ ++-w \ + --table filter \ + --insert LIBVIRT_FWI \ + --destination 192.168.122.0/24 \ + --out-interface virbr0 \ + --jump ACCEPT + iptables \ ++-w \ + --table mangle \ + --insert LIBVIRT_PRT \ + --out-interface virbr0 \ +diff --git a/tests/nwfilterebiptablestest.c b/tests/nwfilterebiptablestest.c +index 3e6c335d4e..e70f0e2400 100644 +--- a/tests/nwfilterebiptablestest.c ++++ b/tests/nwfilterebiptablestest.c +@@ -36,34 +36,34 @@ + + + #define VIR_NWFILTER_NEW_RULES_TEARDOWN \ +- "iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" \ +- "iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n" \ +- "iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" \ +- "iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" \ +- "iptables -F FP-vnet0\n" \ +- "iptables -X FP-vnet0\n" \ +- "iptables -F FJ-vnet0\n" \ +- "iptables -X FJ-vnet0\n" \ +- "iptables -F HJ-vnet0\n" \ +- "iptables -X HJ-vnet0\n" \ +- "ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" \ +- "ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n" \ +- "ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" \ +- "ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" \ +- "ip6tables -F FP-vnet0\n" \ +- "ip6tables -X FP-vnet0\n" \ +- "ip6tables -F FJ-vnet0\n" \ +- "ip6tables -X FJ-vnet0\n" \ +- "ip6tables -F HJ-vnet0\n" \ +- "ip6tables -X HJ-vnet0\n" \ +- "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-J-vnet0\n" \ +- "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-P-vnet0\n" \ +- "ebtables -t nat -L libvirt-J-vnet0\n" \ +- "ebtables -t nat -L libvirt-P-vnet0\n" \ +- "ebtables -t nat -F libvirt-J-vnet0\n" \ +- "ebtables -t nat -X libvirt-J-vnet0\n" \ +- "ebtables -t nat -F libvirt-P-vnet0\n" \ +- "ebtables -t nat -X libvirt-P-vnet0\n" ++ "iptables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" \ ++ "iptables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n" \ ++ "iptables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" \ ++ "iptables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" \ ++ "iptables -w -F FP-vnet0\n" \ ++ "iptables -w -X FP-vnet0\n" \ ++ "iptables -w -F FJ-vnet0\n" \ ++ "iptables -w -X FJ-vnet0\n" \ ++ "iptables -w -F HJ-vnet0\n" \ ++ "iptables -w -X HJ-vnet0\n" \ ++ "ip6tables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" \ ++ "ip6tables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n" \ ++ "ip6tables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" \ ++ "ip6tables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" \ ++ "ip6tables -w -F FP-vnet0\n" \ ++ "ip6tables -w -X FP-vnet0\n" \ ++ "ip6tables -w -F FJ-vnet0\n" \ ++ "ip6tables -w -X FJ-vnet0\n" \ ++ "ip6tables -w -F HJ-vnet0\n" \ ++ "ip6tables -w -X HJ-vnet0\n" \ ++ "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-J-vnet0\n" \ ++ "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-P-vnet0\n" \ ++ "ebtables --concurrent -t nat -L libvirt-J-vnet0\n" \ ++ "ebtables --concurrent -t nat -L libvirt-P-vnet0\n" \ ++ "ebtables --concurrent -t nat -F libvirt-J-vnet0\n" \ ++ "ebtables --concurrent -t nat -X libvirt-J-vnet0\n" \ ++ "ebtables --concurrent -t nat -F libvirt-P-vnet0\n" \ ++ "ebtables --concurrent -t nat -X libvirt-P-vnet0\n" + + static int + testNWFilterEBIPTablesAllTeardown(const void *opaque G_GNUC_UNUSED) +@@ -71,36 +71,36 @@ testNWFilterEBIPTablesAllTeardown(const void *opaque G_GNUC_UNUSED) + virBuffer buf = VIR_BUFFER_INITIALIZER; + const char *expected = + VIR_NWFILTER_NEW_RULES_TEARDOWN +- "iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" +- "iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" +- "iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" +- "iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" +- "iptables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" +- "iptables -F FO-vnet0\n" +- "iptables -X FO-vnet0\n" +- "iptables -F FI-vnet0\n" +- "iptables -X FI-vnet0\n" +- "iptables -F HI-vnet0\n" +- "iptables -X HI-vnet0\n" +- "ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" +- "ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" +- "ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" +- "ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" +- "ip6tables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" +- "ip6tables -F FO-vnet0\n" +- "ip6tables -X FO-vnet0\n" +- "ip6tables -F FI-vnet0\n" +- "ip6tables -X FI-vnet0\n" +- "ip6tables -F HI-vnet0\n" +- "ip6tables -X HI-vnet0\n" +- "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n" +- "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n" +- "ebtables -t nat -L libvirt-I-vnet0\n" +- "ebtables -t nat -L libvirt-O-vnet0\n" +- "ebtables -t nat -F libvirt-I-vnet0\n" +- "ebtables -t nat -X libvirt-I-vnet0\n" +- "ebtables -t nat -F libvirt-O-vnet0\n" +- "ebtables -t nat -X libvirt-O-vnet0\n"; ++ "iptables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" ++ "iptables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" ++ "iptables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" ++ "iptables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" ++ "iptables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" ++ "iptables -w -F FO-vnet0\n" ++ "iptables -w -X FO-vnet0\n" ++ "iptables -w -F FI-vnet0\n" ++ "iptables -w -X FI-vnet0\n" ++ "iptables -w -F HI-vnet0\n" ++ "iptables -w -X HI-vnet0\n" ++ "ip6tables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" ++ "ip6tables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" ++ "ip6tables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" ++ "ip6tables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" ++ "ip6tables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" ++ "ip6tables -w -F FO-vnet0\n" ++ "ip6tables -w -X FO-vnet0\n" ++ "ip6tables -w -F FI-vnet0\n" ++ "ip6tables -w -X FI-vnet0\n" ++ "ip6tables -w -F HI-vnet0\n" ++ "ip6tables -w -X HI-vnet0\n" ++ "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-O-vnet0\n"; + char *actual = NULL; + int ret = -1; + +@@ -131,44 +131,44 @@ testNWFilterEBIPTablesTearOldRules(const void *opaque G_GNUC_UNUSED) + { + virBuffer buf = VIR_BUFFER_INITIALIZER; + const char *expected = +- "iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" +- "iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" +- "iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" +- "iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" +- "iptables -F FO-vnet0\n" +- "iptables -X FO-vnet0\n" +- "iptables -F FI-vnet0\n" +- "iptables -X FI-vnet0\n" +- "iptables -F HI-vnet0\n" +- "iptables -X HI-vnet0\n" +- "iptables -E FP-vnet0 FO-vnet0\n" +- "iptables -E FJ-vnet0 FI-vnet0\n" +- "iptables -E HJ-vnet0 HI-vnet0\n" +- "ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" +- "ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" +- "ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" +- "ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" +- "ip6tables -F FO-vnet0\n" +- "ip6tables -X FO-vnet0\n" +- "ip6tables -F FI-vnet0\n" +- "ip6tables -X FI-vnet0\n" +- "ip6tables -F HI-vnet0\n" +- "ip6tables -X HI-vnet0\n" +- "ip6tables -E FP-vnet0 FO-vnet0\n" +- "ip6tables -E FJ-vnet0 FI-vnet0\n" +- "ip6tables -E HJ-vnet0 HI-vnet0\n" +- "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n" +- "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n" +- "ebtables -t nat -L libvirt-I-vnet0\n" +- "ebtables -t nat -L libvirt-O-vnet0\n" +- "ebtables -t nat -F libvirt-I-vnet0\n" +- "ebtables -t nat -X libvirt-I-vnet0\n" +- "ebtables -t nat -F libvirt-O-vnet0\n" +- "ebtables -t nat -X libvirt-O-vnet0\n" +- "ebtables -t nat -L libvirt-J-vnet0\n" +- "ebtables -t nat -L libvirt-P-vnet0\n" +- "ebtables -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n" +- "ebtables -t nat -E libvirt-P-vnet0 libvirt-O-vnet0\n"; ++ "iptables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" ++ "iptables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" ++ "iptables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" ++ "iptables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" ++ "iptables -w -F FO-vnet0\n" ++ "iptables -w -X FO-vnet0\n" ++ "iptables -w -F FI-vnet0\n" ++ "iptables -w -X FI-vnet0\n" ++ "iptables -w -F HI-vnet0\n" ++ "iptables -w -X HI-vnet0\n" ++ "iptables -w -E FP-vnet0 FO-vnet0\n" ++ "iptables -w -E FJ-vnet0 FI-vnet0\n" ++ "iptables -w -E HJ-vnet0 HI-vnet0\n" ++ "ip6tables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" ++ "ip6tables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" ++ "ip6tables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" ++ "ip6tables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" ++ "ip6tables -w -F FO-vnet0\n" ++ "ip6tables -w -X FO-vnet0\n" ++ "ip6tables -w -F FI-vnet0\n" ++ "ip6tables -w -X FI-vnet0\n" ++ "ip6tables -w -F HI-vnet0\n" ++ "ip6tables -w -X HI-vnet0\n" ++ "ip6tables -w -E FP-vnet0 FO-vnet0\n" ++ "ip6tables -w -E FJ-vnet0 FI-vnet0\n" ++ "ip6tables -w -E HJ-vnet0 HI-vnet0\n" ++ "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-P-vnet0\n" ++ "ebtables --concurrent -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -E libvirt-P-vnet0 libvirt-O-vnet0\n"; + char *actual = NULL; + int ret = -1; + +@@ -199,22 +199,22 @@ testNWFilterEBIPTablesRemoveBasicRules(const void *opaque G_GNUC_UNUSED) + { + virBuffer buf = VIR_BUFFER_INITIALIZER; + const char *expected = +- "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n" +- "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n" +- "ebtables -t nat -L libvirt-I-vnet0\n" +- "ebtables -t nat -L libvirt-O-vnet0\n" +- "ebtables -t nat -F libvirt-I-vnet0\n" +- "ebtables -t nat -X libvirt-I-vnet0\n" +- "ebtables -t nat -F libvirt-O-vnet0\n" +- "ebtables -t nat -X libvirt-O-vnet0\n" +- "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-J-vnet0\n" +- "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-P-vnet0\n" +- "ebtables -t nat -L libvirt-J-vnet0\n" +- "ebtables -t nat -L libvirt-P-vnet0\n" +- "ebtables -t nat -F libvirt-J-vnet0\n" +- "ebtables -t nat -X libvirt-J-vnet0\n" +- "ebtables -t nat -F libvirt-P-vnet0\n" +- "ebtables -t nat -X libvirt-P-vnet0\n"; ++ "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-P-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-P-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-P-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-P-vnet0\n"; + char *actual = NULL; + int ret = -1; + +@@ -277,43 +277,43 @@ testNWFilterEBIPTablesApplyBasicRules(const void *opaque G_GNUC_UNUSED) + virBuffer buf = VIR_BUFFER_INITIALIZER; + const char *expected = + VIR_NWFILTER_NEW_RULES_TEARDOWN +- "iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" +- "iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" +- "iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" +- "iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" +- "iptables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" +- "iptables -F FO-vnet0\n" +- "iptables -X FO-vnet0\n" +- "iptables -F FI-vnet0\n" +- "iptables -X FI-vnet0\n" +- "iptables -F HI-vnet0\n" +- "iptables -X HI-vnet0\n" +- "ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" +- "ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" +- "ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" +- "ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" +- "ip6tables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" +- "ip6tables -F FO-vnet0\n" +- "ip6tables -X FO-vnet0\n" +- "ip6tables -F FI-vnet0\n" +- "ip6tables -X FI-vnet0\n" +- "ip6tables -F HI-vnet0\n" +- "ip6tables -X HI-vnet0\n" +- "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n" +- "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n" +- "ebtables -t nat -L libvirt-I-vnet0\n" +- "ebtables -t nat -L libvirt-O-vnet0\n" +- "ebtables -t nat -F libvirt-I-vnet0\n" +- "ebtables -t nat -X libvirt-I-vnet0\n" +- "ebtables -t nat -F libvirt-O-vnet0\n" +- "ebtables -t nat -X libvirt-O-vnet0\n" +- "ebtables -t nat -N libvirt-J-vnet0\n" +- "ebtables -t nat -A libvirt-J-vnet0 -s '!' 10:20:30:40:50:60 -j DROP\n" +- "ebtables -t nat -A libvirt-J-vnet0 -p IPv4 -j ACCEPT\n" +- "ebtables -t nat -A libvirt-J-vnet0 -p ARP -j ACCEPT\n" +- "ebtables -t nat -A libvirt-J-vnet0 -j DROP\n" +- "ebtables -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n" +- "ebtables -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n"; ++ "iptables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" ++ "iptables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" ++ "iptables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" ++ "iptables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" ++ "iptables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" ++ "iptables -w -F FO-vnet0\n" ++ "iptables -w -X FO-vnet0\n" ++ "iptables -w -F FI-vnet0\n" ++ "iptables -w -X FI-vnet0\n" ++ "iptables -w -F HI-vnet0\n" ++ "iptables -w -X HI-vnet0\n" ++ "ip6tables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" ++ "ip6tables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" ++ "ip6tables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" ++ "ip6tables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" ++ "ip6tables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" ++ "ip6tables -w -F FO-vnet0\n" ++ "ip6tables -w -X FO-vnet0\n" ++ "ip6tables -w -F FI-vnet0\n" ++ "ip6tables -w -X FI-vnet0\n" ++ "ip6tables -w -F HI-vnet0\n" ++ "ip6tables -w -X HI-vnet0\n" ++ "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -N libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -A libvirt-J-vnet0 -s '!' 10:20:30:40:50:60 -j DROP\n" ++ "ebtables --concurrent -t nat -A libvirt-J-vnet0 -p IPv4 -j ACCEPT\n" ++ "ebtables --concurrent -t nat -A libvirt-J-vnet0 -p ARP -j ACCEPT\n" ++ "ebtables --concurrent -t nat -A libvirt-J-vnet0 -j DROP\n" ++ "ebtables --concurrent -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n"; + char *actual = NULL; + int ret = -1; + virMacAddr mac = { .addr = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 } }; +@@ -346,51 +346,51 @@ testNWFilterEBIPTablesApplyDHCPOnlyRules(const void *opaque G_GNUC_UNUSED) + virBuffer buf = VIR_BUFFER_INITIALIZER; + const char *expected = + VIR_NWFILTER_NEW_RULES_TEARDOWN +- "iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" +- "iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" +- "iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" +- "iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" +- "iptables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" +- "iptables -F FO-vnet0\n" +- "iptables -X FO-vnet0\n" +- "iptables -F FI-vnet0\n" +- "iptables -X FI-vnet0\n" +- "iptables -F HI-vnet0\n" +- "iptables -X HI-vnet0\n" +- "ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" +- "ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" +- "ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" +- "ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" +- "ip6tables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" +- "ip6tables -F FO-vnet0\n" +- "ip6tables -X FO-vnet0\n" +- "ip6tables -F FI-vnet0\n" +- "ip6tables -X FI-vnet0\n" +- "ip6tables -F HI-vnet0\n" +- "ip6tables -X HI-vnet0\n" +- "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n" +- "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n" +- "ebtables -t nat -L libvirt-I-vnet0\n" +- "ebtables -t nat -L libvirt-O-vnet0\n" +- "ebtables -t nat -F libvirt-I-vnet0\n" +- "ebtables -t nat -X libvirt-I-vnet0\n" +- "ebtables -t nat -F libvirt-O-vnet0\n" +- "ebtables -t nat -X libvirt-O-vnet0\n" +- "ebtables -t nat -N libvirt-J-vnet0\n" +- "ebtables -t nat -N libvirt-P-vnet0\n" +- "ebtables -t nat -A libvirt-J-vnet0 -s 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-sport 68 --ip-dport 67 -j ACCEPT\n" +- "ebtables -t nat -A libvirt-J-vnet0 -j DROP\n" +- "ebtables -t nat -A libvirt-P-vnet0 -d 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-src 192.168.122.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n" +- "ebtables -t nat -A libvirt-P-vnet0 -d ff:ff:ff:ff:ff:ff -p ipv4 --ip-protocol udp --ip-src 192.168.122.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n" +- "ebtables -t nat -A libvirt-P-vnet0 -d 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-src 10.0.0.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n" +- "ebtables -t nat -A libvirt-P-vnet0 -d ff:ff:ff:ff:ff:ff -p ipv4 --ip-protocol udp --ip-src 10.0.0.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n" +- "ebtables -t nat -A libvirt-P-vnet0 -d 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-src 10.0.0.2 --ip-sport 67 --ip-dport 68 -j ACCEPT\n" +- "ebtables -t nat -A libvirt-P-vnet0 -d ff:ff:ff:ff:ff:ff -p ipv4 --ip-protocol udp --ip-src 10.0.0.2 --ip-sport 67 --ip-dport 68 -j ACCEPT\n" +- "ebtables -t nat -A libvirt-P-vnet0 -j DROP\n" +- "ebtables -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n" +- "ebtables -t nat -A POSTROUTING -o vnet0 -j libvirt-P-vnet0\n" +- "ebtables -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n" +- "ebtables -t nat -E libvirt-P-vnet0 libvirt-O-vnet0\n"; ++ "iptables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" ++ "iptables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" ++ "iptables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" ++ "iptables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" ++ "iptables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" ++ "iptables -w -F FO-vnet0\n" ++ "iptables -w -X FO-vnet0\n" ++ "iptables -w -F FI-vnet0\n" ++ "iptables -w -X FI-vnet0\n" ++ "iptables -w -F HI-vnet0\n" ++ "iptables -w -X HI-vnet0\n" ++ "ip6tables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" ++ "ip6tables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" ++ "ip6tables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" ++ "ip6tables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" ++ "ip6tables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" ++ "ip6tables -w -F FO-vnet0\n" ++ "ip6tables -w -X FO-vnet0\n" ++ "ip6tables -w -F FI-vnet0\n" ++ "ip6tables -w -X FI-vnet0\n" ++ "ip6tables -w -F HI-vnet0\n" ++ "ip6tables -w -X HI-vnet0\n" ++ "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -N libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -N libvirt-P-vnet0\n" ++ "ebtables --concurrent -t nat -A libvirt-J-vnet0 -s 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-sport 68 --ip-dport 67 -j ACCEPT\n" ++ "ebtables --concurrent -t nat -A libvirt-J-vnet0 -j DROP\n" ++ "ebtables --concurrent -t nat -A libvirt-P-vnet0 -d 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-src 192.168.122.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n" ++ "ebtables --concurrent -t nat -A libvirt-P-vnet0 -d ff:ff:ff:ff:ff:ff -p ipv4 --ip-protocol udp --ip-src 192.168.122.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n" ++ "ebtables --concurrent -t nat -A libvirt-P-vnet0 -d 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-src 10.0.0.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n" ++ "ebtables --concurrent -t nat -A libvirt-P-vnet0 -d ff:ff:ff:ff:ff:ff -p ipv4 --ip-protocol udp --ip-src 10.0.0.1 --ip-sport 67 --ip-dport 68 -j ACCEPT\n" ++ "ebtables --concurrent -t nat -A libvirt-P-vnet0 -d 10:20:30:40:50:60 -p ipv4 --ip-protocol udp --ip-src 10.0.0.2 --ip-sport 67 --ip-dport 68 -j ACCEPT\n" ++ "ebtables --concurrent -t nat -A libvirt-P-vnet0 -d ff:ff:ff:ff:ff:ff -p ipv4 --ip-protocol udp --ip-src 10.0.0.2 --ip-sport 67 --ip-dport 68 -j ACCEPT\n" ++ "ebtables --concurrent -t nat -A libvirt-P-vnet0 -j DROP\n" ++ "ebtables --concurrent -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -A POSTROUTING -o vnet0 -j libvirt-P-vnet0\n" ++ "ebtables --concurrent -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -E libvirt-P-vnet0 libvirt-O-vnet0\n"; + char *actual = NULL; + int ret = -1; + virMacAddr mac = { .addr = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 } }; +@@ -434,44 +434,44 @@ testNWFilterEBIPTablesApplyDropAllRules(const void *opaque G_GNUC_UNUSED) + virBuffer buf = VIR_BUFFER_INITIALIZER; + const char *expected = + VIR_NWFILTER_NEW_RULES_TEARDOWN +- "iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" +- "iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" +- "iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" +- "iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" +- "iptables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" +- "iptables -F FO-vnet0\n" +- "iptables -X FO-vnet0\n" +- "iptables -F FI-vnet0\n" +- "iptables -X FI-vnet0\n" +- "iptables -F HI-vnet0\n" +- "iptables -X HI-vnet0\n" +- "ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" +- "ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" +- "ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" +- "ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" +- "ip6tables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" +- "ip6tables -F FO-vnet0\n" +- "ip6tables -X FO-vnet0\n" +- "ip6tables -F FI-vnet0\n" +- "ip6tables -X FI-vnet0\n" +- "ip6tables -F HI-vnet0\n" +- "ip6tables -X HI-vnet0\n" +- "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n" +- "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n" +- "ebtables -t nat -L libvirt-I-vnet0\n" +- "ebtables -t nat -L libvirt-O-vnet0\n" +- "ebtables -t nat -F libvirt-I-vnet0\n" +- "ebtables -t nat -X libvirt-I-vnet0\n" +- "ebtables -t nat -F libvirt-O-vnet0\n" +- "ebtables -t nat -X libvirt-O-vnet0\n" +- "ebtables -t nat -N libvirt-J-vnet0\n" +- "ebtables -t nat -N libvirt-P-vnet0\n" +- "ebtables -t nat -A libvirt-J-vnet0 -j DROP\n" +- "ebtables -t nat -A libvirt-P-vnet0 -j DROP\n" +- "ebtables -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n" +- "ebtables -t nat -A POSTROUTING -o vnet0 -j libvirt-P-vnet0\n" +- "ebtables -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n" +- "ebtables -t nat -E libvirt-P-vnet0 libvirt-O-vnet0\n"; ++ "iptables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" ++ "iptables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" ++ "iptables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" ++ "iptables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" ++ "iptables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" ++ "iptables -w -F FO-vnet0\n" ++ "iptables -w -X FO-vnet0\n" ++ "iptables -w -F FI-vnet0\n" ++ "iptables -w -X FI-vnet0\n" ++ "iptables -w -F HI-vnet0\n" ++ "iptables -w -X HI-vnet0\n" ++ "ip6tables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FO-vnet0\n" ++ "ip6tables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FO-vnet0\n" ++ "ip6tables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FI-vnet0\n" ++ "ip6tables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HI-vnet0\n" ++ "ip6tables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" ++ "ip6tables -w -F FO-vnet0\n" ++ "ip6tables -w -X FO-vnet0\n" ++ "ip6tables -w -F FI-vnet0\n" ++ "ip6tables -w -X FI-vnet0\n" ++ "ip6tables -w -F HI-vnet0\n" ++ "ip6tables -w -X HI-vnet0\n" ++ "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-O-vnet0\n" ++ "ebtables --concurrent -t nat -N libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -N libvirt-P-vnet0\n" ++ "ebtables --concurrent -t nat -A libvirt-J-vnet0 -j DROP\n" ++ "ebtables --concurrent -t nat -A libvirt-P-vnet0 -j DROP\n" ++ "ebtables --concurrent -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -A POSTROUTING -o vnet0 -j libvirt-P-vnet0\n" ++ "ebtables --concurrent -t nat -E libvirt-J-vnet0 libvirt-I-vnet0\n" ++ "ebtables --concurrent -t nat -E libvirt-P-vnet0 libvirt-O-vnet0\n"; + char *actual = NULL; + int ret = -1; + +diff --git a/tests/nwfilterxml2firewalldata/ah-ipv6-linux.args b/tests/nwfilterxml2firewalldata/ah-ipv6-linux.args +index 35c9de38b8..77f0532fd2 100644 +--- a/tests/nwfilterxml2firewalldata/ah-ipv6-linux.args ++++ b/tests/nwfilterxml2firewalldata/ah-ipv6-linux.args +@@ -1,4 +1,5 @@ + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p ah \ + -m mac \ +@@ -11,6 +12,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p ah \ + --destination f:e:d::c:b:a/127 \ +@@ -21,6 +23,7 @@ ip6tables \ + --state ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p ah \ + -m mac \ +@@ -33,6 +36,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p ah \ + --destination a:b:c::/128 \ +@@ -42,6 +46,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p ah \ + -m mac \ +@@ -53,6 +58,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p ah \ + --destination a:b:c::/128 \ +@@ -62,6 +68,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p ah \ + --destination ::10.1.2.3/128 \ +@@ -71,6 +78,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p ah \ + -m mac \ +@@ -82,6 +90,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p ah \ + --destination ::10.1.2.3/128 \ +diff --git a/tests/nwfilterxml2firewalldata/ah-linux.args b/tests/nwfilterxml2firewalldata/ah-linux.args +index 269636754e..c7e5c1eb17 100644 +--- a/tests/nwfilterxml2firewalldata/ah-linux.args ++++ b/tests/nwfilterxml2firewalldata/ah-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p ah \ + -m mac \ +@@ -10,6 +11,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p ah \ + --source 10.1.2.3/32 \ +@@ -19,6 +21,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p ah \ + -m mac \ +@@ -30,6 +33,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p ah \ + --destination 10.1.2.3/22 \ +@@ -39,6 +43,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p ah \ + -m mac \ +@@ -50,6 +55,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p ah \ + --destination 10.1.2.3/22 \ +@@ -59,6 +65,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p ah \ + --destination 10.1.2.3/22 \ +@@ -68,6 +75,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p ah \ + -m mac \ +@@ -79,6 +87,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p ah \ + --destination 10.1.2.3/22 \ +diff --git a/tests/nwfilterxml2firewalldata/all-ipv6-linux.args b/tests/nwfilterxml2firewalldata/all-ipv6-linux.args +index 2f84c1bfea..d86908663c 100644 +--- a/tests/nwfilterxml2firewalldata/all-ipv6-linux.args ++++ b/tests/nwfilterxml2firewalldata/all-ipv6-linux.args +@@ -1,4 +1,5 @@ + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m mac \ +@@ -11,6 +12,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p all \ + --destination f:e:d::c:b:a/127 \ +@@ -21,6 +23,7 @@ ip6tables \ + --state ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m mac \ +@@ -33,6 +36,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + --destination a:b:c::/128 \ +@@ -42,6 +46,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m mac \ +@@ -53,6 +58,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + --destination a:b:c::/128 \ +@@ -62,6 +68,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + --destination ::10.1.2.3/128 \ +@@ -71,6 +78,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m mac \ +@@ -82,6 +90,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + --destination ::10.1.2.3/128 \ +diff --git a/tests/nwfilterxml2firewalldata/all-linux.args b/tests/nwfilterxml2firewalldata/all-linux.args +index 7ea769f74f..187d9ed9ca 100644 +--- a/tests/nwfilterxml2firewalldata/all-linux.args ++++ b/tests/nwfilterxml2firewalldata/all-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m mac \ +@@ -10,6 +11,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + --source 10.1.2.3/32 \ +@@ -19,6 +21,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m mac \ +@@ -30,6 +33,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + --destination 10.1.2.3/22 \ +@@ -39,6 +43,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m mac \ +@@ -50,6 +55,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + --destination 10.1.2.3/22 \ +@@ -59,6 +65,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + --destination 10.1.2.3/22 \ +@@ -68,6 +75,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m mac \ +@@ -79,6 +87,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + --destination 10.1.2.3/22 \ +diff --git a/tests/nwfilterxml2firewalldata/arp-linux.args b/tests/nwfilterxml2firewalldata/arp-linux.args +index b1360175c4..ef9f44d7bb 100644 +--- a/tests/nwfilterxml2firewalldata/arp-linux.args ++++ b/tests/nwfilterxml2firewalldata/arp-linux.args +@@ -1,4 +1,5 @@ + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -11,6 +12,7 @@ ebtables \ + --arp-mac-dst 0a:0b:0c:0d:0e:0f \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -20,6 +22,7 @@ ebtables \ + --arp-ptype 0xff \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -29,6 +32,7 @@ ebtables \ + --arp-ptype 0x100 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -38,6 +42,7 @@ ebtables \ + --arp-ptype 0xffff \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -p 0x806 \ +diff --git a/tests/nwfilterxml2firewalldata/comment-linux.args b/tests/nwfilterxml2firewalldata/comment-linux.args +index 462b2e2177..6233ccf9f5 100644 +--- a/tests/nwfilterxml2firewalldata/comment-linux.args ++++ b/tests/nwfilterxml2firewalldata/comment-linux.args +@@ -1,9 +1,11 @@ + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -p 0x1234 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -17,6 +19,7 @@ ebtables \ + --ip-tos 0x32 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:fe \ +@@ -29,6 +32,7 @@ ebtables \ + --ip6-destination-port 13107:65535 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -41,6 +45,7 @@ ebtables \ + --arp-mac-dst 0a:0b:0c:0d:0e:0f \ + -j ACCEPT + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + -m mac \ +@@ -56,6 +61,7 @@ iptables \ + --comment 'udp rule' \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --source 10.1.2.3/32 \ +@@ -69,6 +75,7 @@ iptables \ + --comment 'udp rule' \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + -m mac \ +@@ -84,6 +91,7 @@ iptables \ + --comment 'udp rule' \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --destination a:b:c::/128 \ +@@ -97,6 +105,7 @@ ip6tables \ + --comment 'tcp/ipv6 rule' \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + -m mac \ +@@ -112,6 +121,7 @@ ip6tables \ + --comment 'tcp/ipv6 rule' \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --destination a:b:c::/128 \ +@@ -125,6 +135,7 @@ ip6tables \ + --comment 'tcp/ipv6 rule' \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + -m state \ +@@ -133,6 +144,7 @@ ip6tables \ + --comment '`ls`;${COLUMNS};$(ls);"test";&'\''3 spaces'\''' \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + -m state \ +@@ -141,6 +153,7 @@ ip6tables \ + --comment '`ls`;${COLUMNS};$(ls);"test";&'\''3 spaces'\''' \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + -m state \ +@@ -149,6 +162,7 @@ ip6tables \ + --comment '`ls`;${COLUMNS};$(ls);"test";&'\''3 spaces'\''' \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + -m state \ +@@ -157,6 +171,7 @@ ip6tables \ + --comment 'comment with lone '\'', `, ", `, \, $x, and two spaces' \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + -m state \ +@@ -165,6 +180,7 @@ ip6tables \ + --comment 'comment with lone '\'', `, ", `, \, $x, and two spaces' \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + -m state \ +@@ -173,6 +189,7 @@ ip6tables \ + --comment 'comment with lone '\'', `, ", `, \, $x, and two spaces' \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p ah \ + -m state \ +@@ -182,6 +199,7 @@ ip6tables \ + -f ${tmp}' \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p ah \ + -m state \ +@@ -191,6 +209,7 @@ ip6tables \ + -f ${tmp}' \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p ah \ + -m state \ +diff --git a/tests/nwfilterxml2firewalldata/conntrack-linux.args b/tests/nwfilterxml2firewalldata/conntrack-linux.args +index c653049e8e..78495598a1 100644 +--- a/tests/nwfilterxml2firewalldata/conntrack-linux.args ++++ b/tests/nwfilterxml2firewalldata/conntrack-linux.args +@@ -1,40 +1,47 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p icmp \ + -m connlimit \ + --connlimit-above 1 \ + -j DROP + iptables \ ++-w \ + -A HJ-vnet0 \ + -p icmp \ + -m connlimit \ + --connlimit-above 1 \ + -j DROP + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + -m connlimit \ + --connlimit-above 2 \ + -j DROP + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + -m connlimit \ + --connlimit-above 2 \ + -j DROP + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m state \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m state \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m state \ +diff --git a/tests/nwfilterxml2firewalldata/esp-ipv6-linux.args b/tests/nwfilterxml2firewalldata/esp-ipv6-linux.args +index 51cf74815b..22dad0b412 100644 +--- a/tests/nwfilterxml2firewalldata/esp-ipv6-linux.args ++++ b/tests/nwfilterxml2firewalldata/esp-ipv6-linux.args +@@ -1,4 +1,5 @@ + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p esp \ + -m mac \ +@@ -11,6 +12,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p esp \ + --destination f:e:d::c:b:a/127 \ +@@ -21,6 +23,7 @@ ip6tables \ + --state ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p esp \ + -m mac \ +@@ -33,6 +36,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p esp \ + --destination a:b:c::/128 \ +@@ -42,6 +46,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p esp \ + -m mac \ +@@ -53,6 +58,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p esp \ + --destination a:b:c::/128 \ +@@ -62,6 +68,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p esp \ + --destination ::10.1.2.3/128 \ +@@ -71,6 +78,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p esp \ + -m mac \ +@@ -82,6 +90,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p esp \ + --destination ::10.1.2.3/128 \ +diff --git a/tests/nwfilterxml2firewalldata/esp-linux.args b/tests/nwfilterxml2firewalldata/esp-linux.args +index 17acb8133c..7cd70afaa1 100644 +--- a/tests/nwfilterxml2firewalldata/esp-linux.args ++++ b/tests/nwfilterxml2firewalldata/esp-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p esp \ + -m mac \ +@@ -10,6 +11,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p esp \ + --source 10.1.2.3/32 \ +@@ -19,6 +21,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p esp \ + -m mac \ +@@ -30,6 +33,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p esp \ + --destination 10.1.2.3/22 \ +@@ -39,6 +43,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p esp \ + -m mac \ +@@ -50,6 +55,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p esp \ + --destination 10.1.2.3/22 \ +@@ -59,6 +65,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p esp \ + --destination 10.1.2.3/22 \ +@@ -68,6 +75,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p esp \ + -m mac \ +@@ -79,6 +87,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p esp \ + --destination 10.1.2.3/22 \ +diff --git a/tests/nwfilterxml2firewalldata/example-1-linux.args b/tests/nwfilterxml2firewalldata/example-1-linux.args +index c5549f8dd6..1cc3746d40 100644 +--- a/tests/nwfilterxml2firewalldata/example-1-linux.args ++++ b/tests/nwfilterxml2firewalldata/example-1-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --sport 22 \ +@@ -6,6 +7,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --dport 22 \ +@@ -13,6 +15,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --sport 22 \ +@@ -20,50 +23,59 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p icmp \ + -m state \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p icmp \ + -m state \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p icmp \ + -m state \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m state \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m state \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m state \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -j DROP + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -j DROP + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -j DROP +diff --git a/tests/nwfilterxml2firewalldata/example-2-linux.args b/tests/nwfilterxml2firewalldata/example-2-linux.args +index 2db58f1e0f..87462ad954 100644 +--- a/tests/nwfilterxml2firewalldata/example-2-linux.args ++++ b/tests/nwfilterxml2firewalldata/example-2-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m state \ +@@ -7,6 +8,7 @@ iptables \ + --comment 'out: existing and related (ftp) connections' \ + -j RETURN + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m state \ +@@ -15,6 +17,7 @@ iptables \ + --comment 'out: existing and related (ftp) connections' \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m state \ +@@ -23,6 +26,7 @@ iptables \ + --comment 'in: existing connections' \ + -j ACCEPT + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --dport 21:22 \ +@@ -32,6 +36,7 @@ iptables \ + --comment 'in: ftp and ssh' \ + -j ACCEPT + iptables \ ++-w \ + -A FP-vnet0 \ + -p icmp \ + -m state \ +@@ -40,6 +45,7 @@ iptables \ + --comment 'in: icmp' \ + -j ACCEPT + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --dport 53 \ +@@ -49,6 +55,7 @@ iptables \ + --comment 'out: DNS lookups' \ + -j RETURN + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --dport 53 \ +@@ -58,18 +65,21 @@ iptables \ + --comment 'out: DNS lookups' \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m comment \ + --comment 'inout: drop all non-accepted traffic' \ + -j DROP + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m comment \ + --comment 'inout: drop all non-accepted traffic' \ + -j DROP + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m comment \ +diff --git a/tests/nwfilterxml2firewalldata/hex-data-linux.args b/tests/nwfilterxml2firewalldata/hex-data-linux.args +index f1a1f588f2..3c04e1c23d 100644 +--- a/tests/nwfilterxml2firewalldata/hex-data-linux.args ++++ b/tests/nwfilterxml2firewalldata/hex-data-linux.args +@@ -1,9 +1,11 @@ + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -p 0x1234 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -17,6 +19,7 @@ ebtables \ + --ip-tos 0x32 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:fe \ +@@ -29,6 +32,7 @@ ebtables \ + --ip6-destination-port 13107:65535 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -41,6 +45,7 @@ ebtables \ + --arp-mac-dst 0a:0b:0c:0d:0e:0f \ + -j ACCEPT + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + -m mac \ +@@ -54,6 +59,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --source 10.1.2.3/32 \ +@@ -65,6 +71,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + -m mac \ +@@ -78,6 +85,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --destination a:b:c::/128 \ +@@ -89,6 +97,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + -m mac \ +@@ -102,6 +111,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --destination a:b:c::/128 \ +diff --git a/tests/nwfilterxml2firewalldata/icmp-direction-linux.args b/tests/nwfilterxml2firewalldata/icmp-direction-linux.args +index 9f481fa831..7548aaeba5 100644 +--- a/tests/nwfilterxml2firewalldata/icmp-direction-linux.args ++++ b/tests/nwfilterxml2firewalldata/icmp-direction-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FP-vnet0 \ + -p icmp \ + --icmp-type 0 \ +@@ -6,6 +7,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A FJ-vnet0 \ + -p icmp \ + --icmp-type 8 \ +@@ -13,6 +15,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A HJ-vnet0 \ + -p icmp \ + --icmp-type 8 \ +@@ -20,14 +23,17 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p icmp \ + -j DROP + iptables \ ++-w \ + -A FP-vnet0 \ + -p icmp \ + -j DROP + iptables \ ++-w \ + -A HJ-vnet0 \ + -p icmp \ + -j DROP +diff --git a/tests/nwfilterxml2firewalldata/icmp-direction2-linux.args b/tests/nwfilterxml2firewalldata/icmp-direction2-linux.args +index 1faa3d880a..026702caee 100644 +--- a/tests/nwfilterxml2firewalldata/icmp-direction2-linux.args ++++ b/tests/nwfilterxml2firewalldata/icmp-direction2-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FP-vnet0 \ + -p icmp \ + --icmp-type 8 \ +@@ -6,6 +7,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A FJ-vnet0 \ + -p icmp \ + --icmp-type 0 \ +@@ -13,6 +15,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A HJ-vnet0 \ + -p icmp \ + --icmp-type 0 \ +@@ -20,14 +23,17 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p icmp \ + -j DROP + iptables \ ++-w \ + -A FP-vnet0 \ + -p icmp \ + -j DROP + iptables \ ++-w \ + -A HJ-vnet0 \ + -p icmp \ + -j DROP +diff --git a/tests/nwfilterxml2firewalldata/icmp-direction3-linux.args b/tests/nwfilterxml2firewalldata/icmp-direction3-linux.args +index 6cc8e132d9..6ee6a4f84a 100644 +--- a/tests/nwfilterxml2firewalldata/icmp-direction3-linux.args ++++ b/tests/nwfilterxml2firewalldata/icmp-direction3-linux.args +@@ -1,30 +1,36 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p icmp \ + -m state \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p icmp \ + -m state \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p icmp \ + -m state \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -j DROP + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -j DROP + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -j DROP +diff --git a/tests/nwfilterxml2firewalldata/icmp-linux.args b/tests/nwfilterxml2firewalldata/icmp-linux.args +index d808f0ea60..d688e29213 100644 +--- a/tests/nwfilterxml2firewalldata/icmp-linux.args ++++ b/tests/nwfilterxml2firewalldata/icmp-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p icmp \ + -m mac \ +@@ -11,6 +12,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A HJ-vnet0 \ + -p icmp \ + -m mac \ +@@ -23,6 +25,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p icmp \ + -m mac \ +diff --git a/tests/nwfilterxml2firewalldata/icmpv6-linux.args b/tests/nwfilterxml2firewalldata/icmpv6-linux.args +index 92190eb311..6e2110fb81 100644 +--- a/tests/nwfilterxml2firewalldata/icmpv6-linux.args ++++ b/tests/nwfilterxml2firewalldata/icmpv6-linux.args +@@ -1,4 +1,5 @@ + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p icmpv6 \ + -m mac \ +@@ -12,6 +13,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p icmpv6 \ + -m mac \ +@@ -25,6 +27,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p icmpv6 \ + -m mac \ +@@ -37,6 +40,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p icmpv6 \ + -m mac \ +diff --git a/tests/nwfilterxml2firewalldata/igmp-linux.args b/tests/nwfilterxml2firewalldata/igmp-linux.args +index 727463a62d..b954b0ae99 100644 +--- a/tests/nwfilterxml2firewalldata/igmp-linux.args ++++ b/tests/nwfilterxml2firewalldata/igmp-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p igmp \ + -m mac \ +@@ -10,6 +11,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p igmp \ + --source 10.1.2.3/32 \ +@@ -19,6 +21,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p igmp \ + -m mac \ +@@ -30,6 +33,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p igmp \ + --destination 10.1.2.3/22 \ +@@ -39,6 +43,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p igmp \ + -m mac \ +@@ -50,6 +55,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p igmp \ + --destination 10.1.2.3/22 \ +@@ -59,6 +65,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p igmp \ + --destination 10.1.2.3/22 \ +@@ -68,6 +75,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p igmp \ + -m mac \ +@@ -79,6 +87,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p igmp \ + --destination 10.1.2.3/22 \ +diff --git a/tests/nwfilterxml2firewalldata/ip-linux.args b/tests/nwfilterxml2firewalldata/ip-linux.args +index 399a47491e..8e64839678 100644 +--- a/tests/nwfilterxml2firewalldata/ip-linux.args ++++ b/tests/nwfilterxml2firewalldata/ip-linux.args +@@ -1,4 +1,5 @@ + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -11,6 +12,7 @@ ebtables \ + --ip-destination-port 100:101 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -p ipv4 \ +@@ -20,6 +22,7 @@ ebtables \ + --ip-tos 0x3f \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -p ipv4 \ +diff --git a/tests/nwfilterxml2firewalldata/ipset-linux.args b/tests/nwfilterxml2firewalldata/ipset-linux.args +index 0fe0739962..5cdb151354 100644 +--- a/tests/nwfilterxml2firewalldata/ipset-linux.args ++++ b/tests/nwfilterxml2firewalldata/ipset-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m state \ +@@ -7,6 +8,7 @@ iptables \ + --match-set tck_test src,dst \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m state \ +@@ -15,6 +17,7 @@ iptables \ + --match-set tck_test dst,src \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m state \ +@@ -23,6 +26,7 @@ iptables \ + --match-set tck_test src,dst \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m set \ +@@ -31,6 +35,7 @@ iptables \ + --comment in+NONE \ + -j ACCEPT + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m set \ +@@ -39,6 +44,7 @@ iptables \ + --comment out+NONE \ + -j RETURN + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m set \ +@@ -47,6 +53,7 @@ iptables \ + --comment out+NONE \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m state \ +@@ -55,6 +62,7 @@ iptables \ + --match-set tck_test dst,src,dst \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m state \ +@@ -63,6 +71,7 @@ iptables \ + --match-set tck_test src,dst,src \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m state \ +@@ -71,6 +80,7 @@ iptables \ + --match-set tck_test dst,src,dst \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m state \ +@@ -79,6 +89,7 @@ iptables \ + --match-set tck_test dst,src,dst \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m state \ +@@ -87,6 +98,7 @@ iptables \ + --match-set tck_test src,dst,src \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m state \ +@@ -95,6 +107,7 @@ iptables \ + --match-set tck_test dst,src,dst \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m state \ +@@ -103,6 +116,7 @@ iptables \ + --match-set tck_test dst,src \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m state \ +@@ -111,6 +125,7 @@ iptables \ + --match-set tck_test src,dst \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m state \ +@@ -119,6 +134,7 @@ iptables \ + --match-set tck_test dst,src \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m set \ +@@ -127,6 +143,7 @@ iptables \ + --comment inout \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m set \ +@@ -135,6 +152,7 @@ iptables \ + --comment inout \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m set \ +diff --git a/tests/nwfilterxml2firewalldata/ipt-no-macspoof-linux.args b/tests/nwfilterxml2firewalldata/ipt-no-macspoof-linux.args +index 86ab228fb8..c35fa1e488 100644 +--- a/tests/nwfilterxml2firewalldata/ipt-no-macspoof-linux.args ++++ b/tests/nwfilterxml2firewalldata/ipt-no-macspoof-linux.args +@@ -1,10 +1,12 @@ + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m mac '!' \ + --mac-source 12:34:56:78:9a:bc \ + -j DROP + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m mac '!' \ +diff --git a/tests/nwfilterxml2firewalldata/ipv6-linux.args b/tests/nwfilterxml2firewalldata/ipv6-linux.args +index 6fba19f2eb..87db9c2979 100644 +--- a/tests/nwfilterxml2firewalldata/ipv6-linux.args ++++ b/tests/nwfilterxml2firewalldata/ipv6-linux.args +@@ -1,4 +1,5 @@ + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:fe \ +@@ -11,6 +12,7 @@ ebtables \ + --ip6-destination-port 100:101 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -p ipv6 \ +@@ -21,6 +23,7 @@ ebtables \ + --ip6-source-port 100:101 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -p ipv6 \ +@@ -31,6 +34,7 @@ ebtables \ + --ip6-destination-port 100:101 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -p ipv6 \ +@@ -41,6 +45,7 @@ ebtables \ + --ip6-source-port 65535:65535 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -p ipv6 \ +@@ -51,6 +56,7 @@ ebtables \ + --ip6-destination-port 65535:65535 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -p ipv6 \ +@@ -59,6 +65,7 @@ ebtables \ + --ip6-protocol 18 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -p ipv6 \ +@@ -67,6 +74,7 @@ ebtables \ + --ip6-protocol 18 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -p ipv6 \ +@@ -76,6 +84,7 @@ ebtables \ + --ip6-icmp-type 1:11/10:11 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -p ipv6 \ +@@ -85,6 +94,7 @@ ebtables \ + --ip6-icmp-type 1:11/10:11 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -p ipv6 \ +@@ -94,6 +104,7 @@ ebtables \ + --ip6-icmp-type 1:1/10:10 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -p ipv6 \ +@@ -103,6 +114,7 @@ ebtables \ + --ip6-icmp-type 1:1/10:10 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -p ipv6 \ +@@ -112,6 +124,7 @@ ebtables \ + --ip6-icmp-type 0:255/10:10 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -p ipv6 \ +@@ -121,6 +134,7 @@ ebtables \ + --ip6-icmp-type 0:255/10:10 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -p ipv6 \ +@@ -130,6 +144,7 @@ ebtables \ + --ip6-icmp-type 1:1/0:255 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -p ipv6 \ +diff --git a/tests/nwfilterxml2firewalldata/iter1-linux.args b/tests/nwfilterxml2firewalldata/iter1-linux.args +index 31f37cf537..9bdad18748 100644 +--- a/tests/nwfilterxml2firewalldata/iter1-linux.args ++++ b/tests/nwfilterxml2firewalldata/iter1-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -9,6 +10,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 1.1.1.1 \ +@@ -19,6 +21,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -29,6 +32,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -39,6 +43,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 2.2.2.2 \ +@@ -49,6 +54,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -59,6 +65,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -69,6 +76,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 3.3.3.3 \ +@@ -79,6 +87,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +diff --git a/tests/nwfilterxml2firewalldata/iter2-linux.args b/tests/nwfilterxml2firewalldata/iter2-linux.args +index 4230a9d524..b088350ee5 100644 +--- a/tests/nwfilterxml2firewalldata/iter2-linux.args ++++ b/tests/nwfilterxml2firewalldata/iter2-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -9,6 +10,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 1.1.1.1 \ +@@ -19,6 +21,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -29,6 +32,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -39,6 +43,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 2.2.2.2 \ +@@ -49,6 +54,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -59,6 +65,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -69,6 +76,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 3.3.3.3 \ +@@ -79,6 +87,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -89,6 +98,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 1.1.1.1 \ +@@ -99,6 +109,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 1.1.1.1 \ +@@ -109,6 +120,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 1.1.1.1 \ +@@ -119,6 +131,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 2.2.2.2 \ +@@ -129,6 +142,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 2.2.2.2 \ +@@ -139,6 +153,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 2.2.2.2 \ +@@ -149,6 +164,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 3.3.3.3 \ +@@ -159,6 +175,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 3.3.3.3 \ +@@ -169,6 +186,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 3.3.3.3 \ +@@ -179,6 +197,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 1.1.1.1 \ +@@ -189,6 +208,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 1.1.1.1 \ +@@ -199,6 +219,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 1.1.1.1 \ +@@ -209,6 +230,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 2.2.2.2 \ +@@ -219,6 +241,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 2.2.2.2 \ +@@ -229,6 +252,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 2.2.2.2 \ +@@ -239,6 +263,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 3.3.3.3 \ +@@ -249,6 +274,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 3.3.3.3 \ +@@ -259,6 +285,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 3.3.3.3 \ +@@ -269,6 +296,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 1.1.1.1 \ +@@ -280,6 +308,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 1.1.1.1 \ +@@ -291,6 +320,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 1.1.1.1 \ +@@ -302,6 +332,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 2.2.2.2 \ +@@ -313,6 +344,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 2.2.2.2 \ +@@ -324,6 +356,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 2.2.2.2 \ +@@ -335,6 +368,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 3.3.3.3 \ +@@ -346,6 +380,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 3.3.3.3 \ +@@ -357,6 +392,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 3.3.3.3 \ +@@ -368,6 +404,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 1.1.1.1 \ +@@ -379,6 +416,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 1.1.1.1 \ +@@ -390,6 +428,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 1.1.1.1 \ +@@ -401,6 +440,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 2.2.2.2 \ +@@ -412,6 +452,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 2.2.2.2 \ +@@ -423,6 +464,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 2.2.2.2 \ +@@ -434,6 +476,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 3.3.3.3 \ +@@ -445,6 +488,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 3.3.3.3 \ +@@ -456,6 +500,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 3.3.3.3 \ +@@ -467,6 +512,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 1.1.1.1 \ +@@ -478,6 +524,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 1.1.1.1 \ +@@ -489,6 +536,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 1.1.1.1 \ +@@ -500,6 +548,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 2.2.2.2 \ +@@ -511,6 +560,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 2.2.2.2 \ +@@ -522,6 +572,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 2.2.2.2 \ +@@ -533,6 +584,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 3.3.3.3 \ +@@ -544,6 +596,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 3.3.3.3 \ +@@ -555,6 +608,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 3.3.3.3 \ +@@ -566,6 +620,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 1.1.1.1 \ +@@ -577,6 +632,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 1.1.1.1 \ +@@ -588,6 +644,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 1.1.1.1 \ +@@ -599,6 +656,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 2.2.2.2 \ +@@ -610,6 +668,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 2.2.2.2 \ +@@ -621,6 +680,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 2.2.2.2 \ +@@ -632,6 +692,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 3.3.3.3 \ +@@ -643,6 +704,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 3.3.3.3 \ +@@ -654,6 +716,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 3.3.3.3 \ +@@ -665,6 +728,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -676,6 +740,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 1.1.1.1 \ +@@ -687,6 +752,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -698,6 +764,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -709,6 +776,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 2.2.2.2 \ +@@ -720,6 +788,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -731,6 +800,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -742,6 +812,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 3.3.3.3 \ +@@ -753,6 +824,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -764,6 +836,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -775,6 +848,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 1.1.1.1 \ +@@ -786,6 +860,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -797,6 +872,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -808,6 +884,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 2.2.2.2 \ +@@ -819,6 +896,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -830,6 +908,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -841,6 +920,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 3.3.3.3 \ +@@ -852,6 +932,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -863,6 +944,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -874,6 +956,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 1.1.1.1 \ +@@ -885,6 +968,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -896,6 +980,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -907,6 +992,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 2.2.2.2 \ +@@ -918,6 +1004,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -929,6 +1016,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -940,6 +1028,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 3.3.3.3 \ +@@ -951,6 +1040,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -962,6 +1052,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -973,6 +1064,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 1.1.1.1 \ +@@ -984,6 +1076,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -995,6 +1088,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -1006,6 +1100,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 2.2.2.2 \ +@@ -1017,6 +1112,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -1028,6 +1124,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -1039,6 +1136,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 3.3.3.3 \ +@@ -1050,6 +1148,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -1061,6 +1160,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -1072,6 +1172,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 1.1.1.1 \ +@@ -1083,6 +1184,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -1094,6 +1196,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -1105,6 +1208,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 2.2.2.2 \ +@@ -1116,6 +1220,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -1127,6 +1232,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -1138,6 +1244,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 3.3.3.3 \ +@@ -1149,6 +1256,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -1160,6 +1268,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -1171,6 +1280,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 1.1.1.1 \ +@@ -1182,6 +1292,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -1193,6 +1304,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -1204,6 +1316,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 2.2.2.2 \ +@@ -1215,6 +1328,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -1226,6 +1340,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -1237,6 +1352,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 3.3.3.3 \ +@@ -1248,6 +1364,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -1259,6 +1376,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -1270,6 +1388,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 1.1.1.1 \ +@@ -1281,6 +1400,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -1292,6 +1412,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -1303,6 +1424,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 2.2.2.2 \ +@@ -1314,6 +1436,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -1325,6 +1448,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -1336,6 +1460,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 3.3.3.3 \ +@@ -1347,6 +1472,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -1358,6 +1484,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -1369,6 +1496,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 1.1.1.1 \ +@@ -1380,6 +1508,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -1391,6 +1520,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -1402,6 +1532,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 2.2.2.2 \ +@@ -1413,6 +1544,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 2.2.2.2 \ +@@ -1424,6 +1556,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -1435,6 +1568,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 3.3.3.3 \ +@@ -1446,6 +1580,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 3.3.3.3 \ +@@ -1457,6 +1592,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 1.1.1.1 \ +@@ -1467,6 +1603,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 1.1.1.1 \ +@@ -1477,6 +1614,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 1.1.1.1 \ +@@ -1487,6 +1625,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 2.2.2.2 \ +@@ -1497,6 +1636,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 2.2.2.2 \ +@@ -1507,6 +1647,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 2.2.2.2 \ +@@ -1517,6 +1658,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 3.3.3.3 \ +@@ -1527,6 +1669,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 3.3.3.3 \ +@@ -1537,6 +1680,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 3.3.3.3 \ +@@ -1547,6 +1691,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 1.1.1.1 \ +@@ -1557,6 +1702,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 1.1.1.1 \ +@@ -1567,6 +1713,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 1.1.1.1 \ +@@ -1577,6 +1724,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 2.2.2.2 \ +@@ -1587,6 +1735,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 2.2.2.2 \ +@@ -1597,6 +1746,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 2.2.2.2 \ +@@ -1607,6 +1757,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 3.3.3.3 \ +@@ -1617,6 +1768,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 3.3.3.3 \ +@@ -1627,6 +1779,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 3.3.3.3 \ +@@ -1637,6 +1790,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 1.1.1.1 \ +@@ -1647,6 +1801,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 1.1.1.1 \ +@@ -1657,6 +1812,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 1.1.1.1 \ +@@ -1667,6 +1823,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 2.2.2.2 \ +@@ -1677,6 +1834,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 2.2.2.2 \ +@@ -1687,6 +1845,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 2.2.2.2 \ +@@ -1697,6 +1856,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 3.3.3.3 \ +@@ -1707,6 +1867,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 3.3.3.3 \ +@@ -1717,6 +1878,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 3.3.3.3 \ +@@ -1727,6 +1889,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 1.1.1.1 \ +@@ -1737,6 +1900,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 1.1.1.1 \ +@@ -1747,6 +1911,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 1.1.1.1 \ +@@ -1757,6 +1922,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 2.2.2.2 \ +@@ -1767,6 +1933,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 2.2.2.2 \ +@@ -1777,6 +1944,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 2.2.2.2 \ +@@ -1787,6 +1955,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 3.3.3.3 \ +@@ -1797,6 +1966,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 3.3.3.3 \ +@@ -1807,6 +1977,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 3.3.3.3 \ +diff --git a/tests/nwfilterxml2firewalldata/iter3-linux.args b/tests/nwfilterxml2firewalldata/iter3-linux.args +index 0b16577992..cc6d442c75 100644 +--- a/tests/nwfilterxml2firewalldata/iter3-linux.args ++++ b/tests/nwfilterxml2firewalldata/iter3-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -9,6 +10,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 1.1.1.1 \ +@@ -19,6 +21,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -29,6 +32,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -39,6 +43,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --destination 1.1.1.1 \ +@@ -49,6 +54,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --source 1.1.1.1 \ +@@ -59,6 +65,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 2.2.2.2 \ +@@ -69,6 +76,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 2.2.2.2 \ +@@ -79,6 +87,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 2.2.2.2 \ +@@ -89,6 +98,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --source 2.2.2.2 \ +@@ -99,6 +109,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --destination 2.2.2.2 \ +@@ -109,6 +120,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --source 2.2.2.2 \ +@@ -119,6 +131,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --source 2.2.2.2 \ +@@ -130,6 +143,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --destination 2.2.2.2 \ +@@ -141,6 +155,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --source 2.2.2.2 \ +diff --git a/tests/nwfilterxml2firewalldata/mac-linux.args b/tests/nwfilterxml2firewalldata/mac-linux.args +index 0fd9dbccc0..cc3aab2b92 100644 +--- a/tests/nwfilterxml2firewalldata/mac-linux.args ++++ b/tests/nwfilterxml2firewalldata/mac-linux.args +@@ -1,22 +1,26 @@ + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ + -p 0x806 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -d aa:bb:cc:dd:ee:ff/ff:ff:ff:ff:ff:ff \ + -p 0x800 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -d aa:bb:cc:dd:ee:ff/ff:ff:ff:ff:ff:ff \ + -p 0x600 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -d aa:bb:cc:dd:ee:ff/ff:ff:ff:ff:ff:ff \ +diff --git a/tests/nwfilterxml2firewalldata/rarp-linux.args b/tests/nwfilterxml2firewalldata/rarp-linux.args +index f5fd6433bd..3e2441818c 100644 +--- a/tests/nwfilterxml2firewalldata/rarp-linux.args ++++ b/tests/nwfilterxml2firewalldata/rarp-linux.args +@@ -1,7 +1,9 @@ + ebtables \ ++--concurrent \ + -t nat \ + -N libvirt-J-vnet0 + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -14,6 +16,7 @@ ebtables \ + --arp-mac-dst 0a:0b:0c:0d:0e:0f \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -23,6 +26,7 @@ ebtables \ + --arp-ptype 0xff \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -32,6 +36,7 @@ ebtables \ + --arp-ptype 0x100 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -41,6 +46,7 @@ ebtables \ + --arp-ptype 0xffff \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A PREROUTING \ + -i vnet0 \ +diff --git a/tests/nwfilterxml2firewalldata/sctp-ipv6-linux.args b/tests/nwfilterxml2firewalldata/sctp-ipv6-linux.args +index 959c4e8e0f..fbe6f39198 100644 +--- a/tests/nwfilterxml2firewalldata/sctp-ipv6-linux.args ++++ b/tests/nwfilterxml2firewalldata/sctp-ipv6-linux.args +@@ -1,4 +1,5 @@ + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + -m mac \ +@@ -10,6 +11,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --source a:b:c::d:e:f/128 \ +@@ -19,6 +21,7 @@ ip6tables \ + --state ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + -m mac \ +@@ -30,6 +33,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --destination a:b:c::/128 \ +@@ -41,6 +45,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + -m mac \ +@@ -54,6 +59,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --destination a:b:c::/128 \ +@@ -65,6 +71,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --destination ::10.1.2.3/128 \ +@@ -76,6 +83,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + -m mac \ +@@ -89,6 +97,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --destination ::10.1.2.3/128 \ +diff --git a/tests/nwfilterxml2firewalldata/sctp-linux.args b/tests/nwfilterxml2firewalldata/sctp-linux.args +index 671fc0480f..a3c5a7a72d 100644 +--- a/tests/nwfilterxml2firewalldata/sctp-linux.args ++++ b/tests/nwfilterxml2firewalldata/sctp-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + -m mac \ +@@ -10,6 +11,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + --source 10.1.2.3/32 \ +@@ -19,6 +21,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + -m mac \ +@@ -30,6 +33,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --destination 10.1.2.3/32 \ +@@ -41,6 +45,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + -m mac \ +@@ -54,6 +59,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --destination 10.1.2.3/32 \ +@@ -65,6 +71,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p sctp \ + --destination 10.1.2.3/32 \ +@@ -76,6 +83,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p sctp \ + -m mac \ +@@ -89,6 +97,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p sctp \ + --destination 10.1.2.3/32 \ +diff --git a/tests/nwfilterxml2firewalldata/stp-linux.args b/tests/nwfilterxml2firewalldata/stp-linux.args +index e3114ac622..76f5321856 100644 +--- a/tests/nwfilterxml2firewalldata/stp-linux.args ++++ b/tests/nwfilterxml2firewalldata/stp-linux.args +@@ -1,32 +1,41 @@ + ebtables \ ++--concurrent \ + -t nat \ + -F J-vnet0-stp-xyz + ebtables \ ++--concurrent \ + -t nat \ + -X J-vnet0-stp-xyz + ebtables \ ++--concurrent \ + -t nat \ + -N J-vnet0-stp-xyz + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -d 01:80:c2:00:00:00 \ + -j J-vnet0-stp-xyz + ebtables \ ++--concurrent \ + -t nat \ + -F P-vnet0-stp-xyz + ebtables \ ++--concurrent \ + -t nat \ + -X P-vnet0-stp-xyz + ebtables \ ++--concurrent \ + -t nat \ + -N P-vnet0-stp-xyz + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -d 01:80:c2:00:00:00 \ + -j P-vnet0-stp-xyz + ebtables \ ++--concurrent \ + -t nat \ + -A P-vnet0-stp-xyz \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -35,6 +44,7 @@ ebtables \ + --stp-flags 68 \ + -j CONTINUE + ebtables \ ++--concurrent \ + -t nat \ + -A J-vnet0-stp-xyz \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -44,6 +54,7 @@ ebtables \ + --stp-root-cost 287454020:573785173 \ + -j RETURN + ebtables \ ++--concurrent \ + -t nat \ + -A P-vnet0-stp-xyz \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +diff --git a/tests/nwfilterxml2firewalldata/target-linux.args b/tests/nwfilterxml2firewalldata/target-linux.args +index d219877716..5216c709dd 100644 +--- a/tests/nwfilterxml2firewalldata/target-linux.args ++++ b/tests/nwfilterxml2firewalldata/target-linux.args +@@ -1,40 +1,47 @@ + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ + -p 0x806 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ + -p 0x806 \ + -j DROP + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ + -p 0x806 \ + -j DROP + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -d aa:bb:cc:dd:ee:ff/ff:ff:ff:ff:ff:ff \ + -p 0x800 \ + -j ACCEPT + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -d aa:bb:cc:dd:ee:ff/ff:ff:ff:ff:ff:ff \ + -p 0x800 \ + -j DROP + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -d aa:bb:cc:dd:ee:ff/ff:ff:ff:ff:ff:ff \ + -p 0x800 \ + -j DROP + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m mac \ +@@ -49,6 +56,7 @@ iptables \ + -- dir out' \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + --source 10.1.2.3/32 \ +@@ -61,6 +69,7 @@ iptables \ + -- dir out' \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m mac \ +@@ -75,6 +84,7 @@ iptables \ + -- dir out' \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m mac \ +@@ -87,6 +97,7 @@ iptables \ + -- dir out' \ + -j DROP + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + --source 10.1.2.3/32 \ +@@ -97,6 +108,7 @@ iptables \ + -- dir out' \ + -j DROP + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m mac \ +@@ -109,6 +121,7 @@ iptables \ + -- dir out' \ + -j DROP + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m mac \ +@@ -121,6 +134,7 @@ iptables \ + -- dir out' \ + -j REJECT + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + --source 10.1.2.3/32 \ +@@ -131,6 +145,7 @@ iptables \ + -- dir out' \ + -j REJECT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m mac \ +@@ -143,6 +158,7 @@ iptables \ + -- dir out' \ + -j REJECT + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + --destination 10.1.2.3/22 \ +@@ -155,6 +171,7 @@ iptables \ + -- dir in' \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m mac \ +@@ -169,6 +186,7 @@ iptables \ + -- dir in' \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + --destination 10.1.2.3/22 \ +@@ -181,6 +199,7 @@ iptables \ + -- dir in' \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + --destination 10.1.2.3/22 \ +@@ -191,6 +210,7 @@ iptables \ + -- dir in' \ + -j DROP + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m mac \ +@@ -203,6 +223,7 @@ iptables \ + -- dir in' \ + -j DROP + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + --destination 10.1.2.3/22 \ +@@ -213,6 +234,7 @@ iptables \ + -- dir in' \ + -j DROP + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + --destination 10.1.2.3/22 \ +@@ -223,6 +245,7 @@ iptables \ + -- dir in' \ + -j REJECT + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m mac \ +@@ -235,6 +258,7 @@ iptables \ + -- dir in' \ + -j REJECT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + --destination 10.1.2.3/22 \ +@@ -245,6 +269,7 @@ iptables \ + -- dir in' \ + -j REJECT + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m comment \ +@@ -252,6 +277,7 @@ iptables \ + -- dir inout' \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m comment \ +@@ -259,6 +285,7 @@ iptables \ + -- dir inout' \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m comment \ +@@ -266,6 +293,7 @@ iptables \ + -- dir inout' \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m comment \ +@@ -273,6 +301,7 @@ iptables \ + -- dir inout' \ + -j DROP + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m comment \ +@@ -280,6 +309,7 @@ iptables \ + -- dir inout' \ + -j DROP + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m comment \ +@@ -287,6 +317,7 @@ iptables \ + -- dir inout' \ + -j DROP + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -m comment \ +@@ -294,6 +325,7 @@ iptables \ + -- dir inout' \ + -j REJECT + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -m comment \ +@@ -301,6 +333,7 @@ iptables \ + -- dir inout' \ + -j REJECT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -m comment \ +diff --git a/tests/nwfilterxml2firewalldata/target2-linux.args b/tests/nwfilterxml2firewalldata/target2-linux.args +index cfa4f589d6..c774f6f24a 100644 +--- a/tests/nwfilterxml2firewalldata/target2-linux.args ++++ b/tests/nwfilterxml2firewalldata/target2-linux.args +@@ -1,19 +1,23 @@ + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --dport 22 \ + -j ACCEPT + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --sport 22 \ + -j RETURN + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --sport 22 \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --sport 80 \ +@@ -21,6 +25,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --dport 80 \ +@@ -28,6 +33,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --sport 80 \ +@@ -35,26 +41,32 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + -j REJECT + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + -j REJECT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + -j REJECT + iptables \ ++-w \ + -A FJ-vnet0 \ + -p all \ + -j DROP + iptables \ ++-w \ + -A FP-vnet0 \ + -p all \ + -j DROP + iptables \ ++-w \ + -A HJ-vnet0 \ + -p all \ + -j DROP +diff --git a/tests/nwfilterxml2firewalldata/tcp-ipv6-linux.args b/tests/nwfilterxml2firewalldata/tcp-ipv6-linux.args +index e6f8de3fca..8fa5e24eff 100644 +--- a/tests/nwfilterxml2firewalldata/tcp-ipv6-linux.args ++++ b/tests/nwfilterxml2firewalldata/tcp-ipv6-linux.args +@@ -1,4 +1,5 @@ + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + -m mac \ +@@ -10,6 +11,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --source a:b:c::d:e:f/128 \ +@@ -19,6 +21,7 @@ ip6tables \ + --state ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + -m mac \ +@@ -30,6 +33,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --destination a:b:c::/128 \ +@@ -41,6 +45,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + -m mac \ +@@ -54,6 +59,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --destination a:b:c::/128 \ +@@ -65,6 +71,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --destination ::10.1.2.3/128 \ +@@ -76,6 +83,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + -m mac \ +@@ -89,6 +97,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --destination ::10.1.2.3/128 \ +diff --git a/tests/nwfilterxml2firewalldata/tcp-linux.args b/tests/nwfilterxml2firewalldata/tcp-linux.args +index 195bfc01e6..74ac4a6733 100644 +--- a/tests/nwfilterxml2firewalldata/tcp-linux.args ++++ b/tests/nwfilterxml2firewalldata/tcp-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + -m mac \ +@@ -10,6 +11,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --source 10.1.2.3/32 \ +@@ -19,6 +21,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + -m mac \ +@@ -30,6 +33,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --destination 10.1.2.3/32 \ +@@ -39,6 +43,7 @@ iptables \ + --sport 100:1111 \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + -m mac \ +@@ -50,6 +55,7 @@ iptables \ + --dport 100:1111 \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --destination 10.1.2.3/32 \ +@@ -59,6 +65,7 @@ iptables \ + --sport 100:1111 \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p tcp \ + --destination 10.1.2.3/32 \ +@@ -68,6 +75,7 @@ iptables \ + --sport 65535:65535 \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + -m mac \ +@@ -79,6 +87,7 @@ iptables \ + --dport 65535:65535 \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p tcp \ + --destination 10.1.2.3/32 \ +@@ -88,21 +97,25 @@ iptables \ + --sport 65535:65535 \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --tcp-flags SYN ALL \ + -j ACCEPT + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --tcp-flags SYN SYN,ACK \ + -j ACCEPT + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --tcp-flags RST NONE \ + -j ACCEPT + iptables \ ++-w \ + -A FP-vnet0 \ + -p tcp \ + --tcp-flags PSH NONE \ +diff --git a/tests/nwfilterxml2firewalldata/udp-ipv6-linux.args b/tests/nwfilterxml2firewalldata/udp-ipv6-linux.args +index 9183c08753..59367ed3d3 100644 +--- a/tests/nwfilterxml2firewalldata/udp-ipv6-linux.args ++++ b/tests/nwfilterxml2firewalldata/udp-ipv6-linux.args +@@ -1,4 +1,5 @@ + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + -m mac \ +@@ -10,6 +11,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --source a:b:c::d:e:f/128 \ +@@ -19,6 +21,7 @@ ip6tables \ + --state ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + -m mac \ +@@ -30,6 +33,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --destination ::a:b:c/128 \ +@@ -41,6 +45,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + -m mac \ +@@ -54,6 +59,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --destination ::a:b:c/128 \ +@@ -65,6 +71,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --destination ::10.1.2.3/128 \ +@@ -76,6 +83,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + -m mac \ +@@ -89,6 +97,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --destination ::10.1.2.3/128 \ +diff --git a/tests/nwfilterxml2firewalldata/udp-linux.args b/tests/nwfilterxml2firewalldata/udp-linux.args +index 910d648a8a..32a8f56dfc 100644 +--- a/tests/nwfilterxml2firewalldata/udp-linux.args ++++ b/tests/nwfilterxml2firewalldata/udp-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + -m mac \ +@@ -10,6 +11,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + --source 10.1.2.3/32 \ +@@ -19,6 +21,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + -m mac \ +@@ -30,6 +33,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --destination 10.1.2.3/32 \ +@@ -41,6 +45,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + -m mac \ +@@ -54,6 +59,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --destination 10.1.2.3/32 \ +@@ -65,6 +71,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udp \ + --destination 10.1.2.3/32 \ +@@ -76,6 +83,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udp \ + -m mac \ +@@ -89,6 +97,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udp \ + --destination 10.1.2.3/32 \ +diff --git a/tests/nwfilterxml2firewalldata/udplite-ipv6-linux.args b/tests/nwfilterxml2firewalldata/udplite-ipv6-linux.args +index 9eb38d7e6d..de564aee36 100644 +--- a/tests/nwfilterxml2firewalldata/udplite-ipv6-linux.args ++++ b/tests/nwfilterxml2firewalldata/udplite-ipv6-linux.args +@@ -1,4 +1,5 @@ + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p udplite \ + -m mac \ +@@ -11,6 +12,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p udplite \ + --destination f:e:d::c:b:a/127 \ +@@ -21,6 +23,7 @@ ip6tables \ + --state ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p udplite \ + -m mac \ +@@ -33,6 +36,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p udplite \ + --destination a:b:c::/128 \ +@@ -42,6 +46,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p udplite \ + -m mac \ +@@ -53,6 +58,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p udplite \ + --destination a:b:c::/128 \ +@@ -62,6 +68,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FJ-vnet0 \ + -p udplite \ + --destination ::10.1.2.3/128 \ +@@ -71,6 +78,7 @@ ip6tables \ + --state ESTABLISHED \ + -j RETURN + ip6tables \ ++-w \ + -A FP-vnet0 \ + -p udplite \ + -m mac \ +@@ -82,6 +90,7 @@ ip6tables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + ip6tables \ ++-w \ + -A HJ-vnet0 \ + -p udplite \ + --destination ::10.1.2.3/128 \ +diff --git a/tests/nwfilterxml2firewalldata/udplite-linux.args b/tests/nwfilterxml2firewalldata/udplite-linux.args +index 53bc667459..8f3a9e8f24 100644 +--- a/tests/nwfilterxml2firewalldata/udplite-linux.args ++++ b/tests/nwfilterxml2firewalldata/udplite-linux.args +@@ -1,4 +1,5 @@ + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udplite \ + -m mac \ +@@ -10,6 +11,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udplite \ + --source 10.1.2.3/32 \ +@@ -19,6 +21,7 @@ iptables \ + --state ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udplite \ + -m mac \ +@@ -30,6 +33,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udplite \ + --destination 10.1.2.3/22 \ +@@ -39,6 +43,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udplite \ + -m mac \ +@@ -50,6 +55,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udplite \ + --destination 10.1.2.3/22 \ +@@ -59,6 +65,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FJ-vnet0 \ + -p udplite \ + --destination 10.1.2.3/22 \ +@@ -68,6 +75,7 @@ iptables \ + --state ESTABLISHED \ + -j RETURN + iptables \ ++-w \ + -A FP-vnet0 \ + -p udplite \ + -m mac \ +@@ -79,6 +87,7 @@ iptables \ + --state NEW,ESTABLISHED \ + -j ACCEPT + iptables \ ++-w \ + -A HJ-vnet0 \ + -p udplite \ + --destination 10.1.2.3/22 \ +diff --git a/tests/nwfilterxml2firewalldata/vlan-linux.args b/tests/nwfilterxml2firewalldata/vlan-linux.args +index 0a8204c4dc..a93c09cfbd 100644 +--- a/tests/nwfilterxml2firewalldata/vlan-linux.args ++++ b/tests/nwfilterxml2firewalldata/vlan-linux.args +@@ -1,4 +1,5 @@ + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -d 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -7,6 +8,7 @@ ebtables \ + --vlan-id 291 \ + -j CONTINUE + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -15,6 +17,7 @@ ebtables \ + --vlan-id 291 \ + -j CONTINUE + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -d 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -23,6 +26,7 @@ ebtables \ + --vlan-id 1234 \ + -j RETURN + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -31,6 +35,7 @@ ebtables \ + --vlan-id 1234 \ + -j RETURN + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-P-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -39,6 +44,7 @@ ebtables \ + --vlan-id 291 \ + -j DROP + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +@@ -47,6 +53,7 @@ ebtables \ + --vlan-encap 2054 \ + -j DROP + ebtables \ ++--concurrent \ + -t nat \ + -A libvirt-J-vnet0 \ + -s 01:02:03:04:05:06/ff:ff:ff:ff:ff:ff \ +diff --git a/tests/nwfilterxml2firewalltest.c b/tests/nwfilterxml2firewalltest.c +index da86ec9463..c97f83b24a 100644 +--- a/tests/nwfilterxml2firewalltest.c ++++ b/tests/nwfilterxml2firewalltest.c +@@ -58,90 +58,90 @@ struct _virNWFilterInst { + + static const char *commonRules[] = { + /* Dropping ebtables rules */ +- "ebtables -t nat -D PREROUTING -i vnet0 -j libvirt-J-vnet0\n" +- "ebtables -t nat -D POSTROUTING -o vnet0 -j libvirt-P-vnet0\n" +- "ebtables -t nat -L libvirt-J-vnet0\n" +- "ebtables -t nat -L libvirt-P-vnet0\n" +- "ebtables -t nat -F libvirt-J-vnet0\n" +- "ebtables -t nat -X libvirt-J-vnet0\n" +- "ebtables -t nat -F libvirt-P-vnet0\n" +- "ebtables -t nat -X libvirt-P-vnet0\n", ++ "ebtables --concurrent -t nat -D PREROUTING -i vnet0 -j libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -D POSTROUTING -o vnet0 -j libvirt-P-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -L libvirt-P-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -F libvirt-P-vnet0\n" ++ "ebtables --concurrent -t nat -X libvirt-P-vnet0\n", + + /* Creating ebtables chains */ +- "ebtables -t nat -N libvirt-J-vnet0\n" +- "ebtables -t nat -N libvirt-P-vnet0\n", ++ "ebtables --concurrent -t nat -N libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -N libvirt-P-vnet0\n", + + /* Dropping iptables rules */ +- "iptables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" +- "iptables -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n" +- "iptables -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" +- "iptables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" +- "iptables -F FP-vnet0\n" +- "iptables -X FP-vnet0\n" +- "iptables -F FJ-vnet0\n" +- "iptables -X FJ-vnet0\n" +- "iptables -F HJ-vnet0\n" +- "iptables -X HJ-vnet0\n", ++ "iptables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" ++ "iptables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n" ++ "iptables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" ++ "iptables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" ++ "iptables -w -F FP-vnet0\n" ++ "iptables -w -X FP-vnet0\n" ++ "iptables -w -F FJ-vnet0\n" ++ "iptables -w -X FJ-vnet0\n" ++ "iptables -w -F HJ-vnet0\n" ++ "iptables -w -X HJ-vnet0\n", + + /* Creating iptables chains */ +- "iptables -N libvirt-in\n" +- "iptables -N libvirt-out\n" +- "iptables -N libvirt-in-post\n" +- "iptables -N libvirt-host-in\n" +- "iptables -D FORWARD -j libvirt-in\n" +- "iptables -D FORWARD -j libvirt-out\n" +- "iptables -D FORWARD -j libvirt-in-post\n" +- "iptables -D INPUT -j libvirt-host-in\n" +- "iptables -I FORWARD 1 -j libvirt-in\n" +- "iptables -I FORWARD 2 -j libvirt-out\n" +- "iptables -I FORWARD 3 -j libvirt-in-post\n" +- "iptables -I INPUT 1 -j libvirt-host-in\n" +- "iptables -N FP-vnet0\n" +- "iptables -N FJ-vnet0\n" +- "iptables -N HJ-vnet0\n" +- "iptables -A libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" +- "iptables -A libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" +- "iptables -A libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" +- "iptables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" +- "iptables -A libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n", ++ "iptables -w -N libvirt-in\n" ++ "iptables -w -N libvirt-out\n" ++ "iptables -w -N libvirt-in-post\n" ++ "iptables -w -N libvirt-host-in\n" ++ "iptables -w -D FORWARD -j libvirt-in\n" ++ "iptables -w -D FORWARD -j libvirt-out\n" ++ "iptables -w -D FORWARD -j libvirt-in-post\n" ++ "iptables -w -D INPUT -j libvirt-host-in\n" ++ "iptables -w -I FORWARD 1 -j libvirt-in\n" ++ "iptables -w -I FORWARD 2 -j libvirt-out\n" ++ "iptables -w -I FORWARD 3 -j libvirt-in-post\n" ++ "iptables -w -I INPUT 1 -j libvirt-host-in\n" ++ "iptables -w -N FP-vnet0\n" ++ "iptables -w -N FJ-vnet0\n" ++ "iptables -w -N HJ-vnet0\n" ++ "iptables -w -A libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" ++ "iptables -w -A libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" ++ "iptables -w -A libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" ++ "iptables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" ++ "iptables -w -A libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n", + + /* Dropping ip6tables rules */ +- "ip6tables -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" +- "ip6tables -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n" +- "ip6tables -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" +- "ip6tables -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" +- "ip6tables -F FP-vnet0\n" +- "ip6tables -X FP-vnet0\n" +- "ip6tables -F FJ-vnet0\n" +- "ip6tables -X FJ-vnet0\n" +- "ip6tables -F HJ-vnet0\n" +- "ip6tables -X HJ-vnet0\n", ++ "ip6tables -w -D libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" ++ "ip6tables -w -D libvirt-out -m physdev --physdev-out vnet0 -g FP-vnet0\n" ++ "ip6tables -w -D libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" ++ "ip6tables -w -D libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" ++ "ip6tables -w -F FP-vnet0\n" ++ "ip6tables -w -X FP-vnet0\n" ++ "ip6tables -w -F FJ-vnet0\n" ++ "ip6tables -w -X FJ-vnet0\n" ++ "ip6tables -w -F HJ-vnet0\n" ++ "ip6tables -w -X HJ-vnet0\n", + + /* Creating ip6tables chains */ +- "ip6tables -N libvirt-in\n" +- "ip6tables -N libvirt-out\n" +- "ip6tables -N libvirt-in-post\n" +- "ip6tables -N libvirt-host-in\n" +- "ip6tables -D FORWARD -j libvirt-in\n" +- "ip6tables -D FORWARD -j libvirt-out\n" +- "ip6tables -D FORWARD -j libvirt-in-post\n" +- "ip6tables -D INPUT -j libvirt-host-in\n" +- "ip6tables -I FORWARD 1 -j libvirt-in\n" +- "ip6tables -I FORWARD 2 -j libvirt-out\n" +- "ip6tables -I FORWARD 3 -j libvirt-in-post\n" +- "ip6tables -I INPUT 1 -j libvirt-host-in\n" +- "ip6tables -N FP-vnet0\n" +- "ip6tables -N FJ-vnet0\n" +- "ip6tables -N HJ-vnet0\n" +- "ip6tables -A libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" +- "ip6tables -A libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" +- "ip6tables -A libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" +- "ip6tables -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" +- "ip6tables -A libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n", ++ "ip6tables -w -N libvirt-in\n" ++ "ip6tables -w -N libvirt-out\n" ++ "ip6tables -w -N libvirt-in-post\n" ++ "ip6tables -w -N libvirt-host-in\n" ++ "ip6tables -w -D FORWARD -j libvirt-in\n" ++ "ip6tables -w -D FORWARD -j libvirt-out\n" ++ "ip6tables -w -D FORWARD -j libvirt-in-post\n" ++ "ip6tables -w -D INPUT -j libvirt-host-in\n" ++ "ip6tables -w -I FORWARD 1 -j libvirt-in\n" ++ "ip6tables -w -I FORWARD 2 -j libvirt-out\n" ++ "ip6tables -w -I FORWARD 3 -j libvirt-in-post\n" ++ "ip6tables -w -I INPUT 1 -j libvirt-host-in\n" ++ "ip6tables -w -N FP-vnet0\n" ++ "ip6tables -w -N FJ-vnet0\n" ++ "ip6tables -w -N HJ-vnet0\n" ++ "ip6tables -w -A libvirt-out -m physdev --physdev-is-bridged --physdev-out vnet0 -g FP-vnet0\n" ++ "ip6tables -w -A libvirt-in -m physdev --physdev-in vnet0 -g FJ-vnet0\n" ++ "ip6tables -w -A libvirt-host-in -m physdev --physdev-in vnet0 -g HJ-vnet0\n" ++ "ip6tables -w -D libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n" ++ "ip6tables -w -A libvirt-in-post -m physdev --physdev-in vnet0 -j ACCEPT\n", + + /* Inserting ebtables rules */ +- "ebtables -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n" +- "ebtables -t nat -A POSTROUTING -o vnet0 -j libvirt-P-vnet0\n", ++ "ebtables --concurrent -t nat -A PREROUTING -i vnet0 -j libvirt-J-vnet0\n" ++ "ebtables --concurrent -t nat -A POSTROUTING -o vnet0 -j libvirt-P-vnet0\n", + }; + + +diff --git a/tests/virfirewalltest.c b/tests/virfirewalltest.c +index 8aba127610..195163a985 100644 +--- a/tests/virfirewalltest.c ++++ b/tests/virfirewalltest.c +@@ -147,17 +147,19 @@ VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block, + "org.firewalld.error", + "something bad happened"); + } else { +- if (nargs == 1 && ++ if (nargs == 2 && + STREQ(type, "ipv4") && +- STREQ(args[0], "-L")) { ++ STREQ(args[0], "-w") && ++ STREQ(args[1], "-L")) { + if (virDBusCreateReply(&reply, + "s", TEST_FILTER_TABLE_LIST) < 0) + goto error; +- } else if (nargs == 3 && ++ } else if (nargs == 4 && + STREQ(type, "ipv4") && +- STREQ(args[0], "-t") && +- STREQ(args[1], "nat") && +- STREQ(args[2], "-L")) { ++ STREQ(args[0], "-w") && ++ STREQ(args[1], "-t") && ++ STREQ(args[2], "nat") && ++ STREQ(args[3], "-L")) { + if (virDBusCreateReply(&reply, + "s", TEST_NAT_TABLE_LIST) < 0) + goto error; +@@ -204,8 +206,8 @@ testFirewallSingleGroup(const void *opaque) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"; ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"; + const struct testFirewallData *data = opaque; + + fwDisabled = data->fwDisabled; +@@ -260,8 +262,8 @@ testFirewallRemoveRule(const void *opaque) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"; ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"; + const struct testFirewallData *data = opaque; + virFirewallRulePtr fwrule; + +@@ -323,10 +325,10 @@ testFirewallManyGroups(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -A INPUT --source-host '!192.168.122.1' --jump REJECT\n" +- IPTABLES_PATH " -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -A OUTPUT --jump DROP\n"; ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n" ++ IPTABLES_PATH " -w -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A OUTPUT --jump DROP\n"; + const struct testFirewallData *data = opaque; + + fwDisabled = data->fwDisabled; +@@ -414,10 +416,10 @@ testFirewallIgnoreFailGroup(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -A OUTPUT --jump DROP\n"; ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A OUTPUT --jump DROP\n"; + const struct testFirewallData *data = opaque; + + fwDisabled = data->fwDisabled; +@@ -486,10 +488,10 @@ testFirewallIgnoreFailRule(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -A OUTPUT --jump DROP\n"; ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -A OUTPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A OUTPUT --jump DROP\n"; + const struct testFirewallData *data = opaque; + + fwDisabled = data->fwDisabled; +@@ -557,8 +559,8 @@ testFirewallNoRollback(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.255 --jump REJECT\n"; ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n"; + const struct testFirewallData *data = opaque; + + fwDisabled = data->fwDisabled; +@@ -621,11 +623,11 @@ testFirewallSingleRollback(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -D INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -D INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -D INPUT --source-host '!192.168.122.1' --jump REJECT\n"; ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n"; + const struct testFirewallData *data = opaque; + + fwDisabled = data->fwDisabled; +@@ -705,10 +707,10 @@ testFirewallManyRollback(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -D INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -D INPUT --source-host '!192.168.122.1' --jump REJECT\n"; ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n"; + const struct testFirewallData *data = opaque; + + fwDisabled = data->fwDisabled; +@@ -792,14 +794,14 @@ testFirewallChainedRollback(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.127 --jump REJECT\n" +- IPTABLES_PATH " -A INPUT --source-host '!192.168.122.1' --jump REJECT\n" +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -D INPUT --source-host 192.168.122.127 --jump REJECT\n" +- IPTABLES_PATH " -D INPUT --source-host '!192.168.122.1' --jump REJECT\n" +- IPTABLES_PATH " -D INPUT --source-host 192.168.122.255 --jump REJECT\n" +- IPTABLES_PATH " -D INPUT --source-host '!192.168.122.1' --jump REJECT\n"; ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.127 --jump REJECT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.127 --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source-host 192.168.122.255 --jump REJECT\n" ++ IPTABLES_PATH " -w -D INPUT --source-host '!192.168.122.1' --jump REJECT\n"; + const struct testFirewallData *data = opaque; + + fwDisabled = data->fwDisabled; +@@ -938,12 +940,14 @@ testFirewallQueryHook(const char *const*args, + void *opaque G_GNUC_UNUSED) + { + if (STREQ(args[0], IPTABLES_PATH) && +- STREQ(args[1], "-L")) { ++ STREQ(args[1], "-w") && ++ STREQ(args[2], "-L")) { + *output = g_strdup(TEST_FILTER_TABLE_LIST); + } else if (STREQ(args[0], IPTABLES_PATH) && +- STREQ(args[1], "-t") && +- STREQ(args[2], "nat") && +- STREQ(args[3], "-L")) { ++ STREQ(args[1], "-w") && ++ STREQ(args[2], "-t") && ++ STREQ(args[3], "nat") && ++ STREQ(args[4], "-L")) { + *output = g_strdup(TEST_NAT_TABLE_LIST); + } + } +@@ -986,15 +990,15 @@ testFirewallQuery(const void *opaque G_GNUC_UNUSED) + int ret = -1; + const char *actual = NULL; + const char *expected = +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.127 --jump REJECT\n" +- IPTABLES_PATH " -L\n" +- IPTABLES_PATH " -t nat -L\n" +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.130 --jump REJECT\n" +- IPTABLES_PATH " -A INPUT --source-host '!192.168.122.129' --jump REJECT\n" +- IPTABLES_PATH " -A INPUT --source-host '!192.168.122.129' --jump REJECT\n" +- IPTABLES_PATH " -A INPUT --source-host 192.168.122.128 --jump REJECT\n" +- IPTABLES_PATH " -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"; ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.1 --jump ACCEPT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.127 --jump REJECT\n" ++ IPTABLES_PATH " -w -L\n" ++ IPTABLES_PATH " -w -t nat -L\n" ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.130 --jump REJECT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.129' --jump REJECT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.129' --jump REJECT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host 192.168.122.128 --jump REJECT\n" ++ IPTABLES_PATH " -w -A INPUT --source-host '!192.168.122.1' --jump REJECT\n"; + const struct testFirewallData *data = opaque; + + expectedLineNum = 0; +-- +2.30.0 + diff --git a/SOURCES/libvirt-util-virNetDevTapCreate-initialize-fd-to-1.patch b/SOURCES/libvirt-util-virNetDevTapCreate-initialize-fd-to-1.patch new file mode 100644 index 0000000..d2a583f --- /dev/null +++ b/SOURCES/libvirt-util-virNetDevTapCreate-initialize-fd-to-1.patch @@ -0,0 +1,37 @@ +From 3b2892c175918021f78a7dfc8dac39f4c451a15f Mon Sep 17 00:00:00 2001 +Message-Id: <3b2892c175918021f78a7dfc8dac39f4c451a15f@dist-git> +From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com> +Date: Sat, 12 Dec 2020 22:04:53 -0500 +Subject: [PATCH] util: virNetDevTapCreate: initialize fd to -1 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Ján Tomko <jtomko@redhat.com> +Fixes: 95089f481e003d971fe0a082018216c58c1b80e5 +(cherry picked from commit 2b6cd855042984b87beb7e3c30b67b0f586d89bb) + +https://bugzilla.redhat.com/1874304 +Signed-off-by: Laine Stump <laine@redhat.com> +Message-Id: <20201213030453.48851-4-laine@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +--- + src/util/virnetdevtap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c +index fd4b70df30..d333163ff9 100644 +--- a/src/util/virnetdevtap.c ++++ b/src/util/virnetdevtap.c +@@ -318,7 +318,7 @@ int virNetDevTapCreate(char **ifname, + size_t i = 0; + struct ifreq ifr; + int ret = -1; +- int fd = 0; ++ int fd = -1; + + virMutexLock(&virNetDevTapCreateMutex); + +-- +2.29.2 + diff --git a/SOURCES/libvirt-util-virhostcpu-Fail-when-fetching-CPU-Stats-for-invalid-cpu.patch b/SOURCES/libvirt-util-virhostcpu-Fail-when-fetching-CPU-Stats-for-invalid-cpu.patch new file mode 100644 index 0000000..34c2060 --- /dev/null +++ b/SOURCES/libvirt-util-virhostcpu-Fail-when-fetching-CPU-Stats-for-invalid-cpu.patch @@ -0,0 +1,102 @@ +From ff54ea3d2a61a25079339d38caa6c509cf697ce3 Mon Sep 17 00:00:00 2001 +Message-Id: <ff54ea3d2a61a25079339d38caa6c509cf697ce3@dist-git> +From: "Mauro S. M. Rodrigues" <maurosr@linux.vnet.ibm.com> +Date: Tue, 19 Jan 2021 21:04:08 -0300 +Subject: [PATCH] util: virhostcpu: Fail when fetching CPU Stats for invalid + cpu + +virHostCPUGetStatsLinux walks through every cpu in /proc/stat until it +finds cpu%cpuNum that matches with the requested cpu. +If none is found it logs the error but it should return -1, instead of 0. +Otherwise virsh nodecpustats --cpu <invalid cpu number> and API bindings +don't fail properly, printing a blank line instead of an error message. + +This patch also includes an additional test for virhostcputest to avoid +this regression to happen again in the future. + +Fixes: 93af79fba3fd75a8df6b7ca608719dd97f9511a0 +Reported-by: Satheesh Rajendran <satheera@in.ibm.com> +Signed-off-by: Mauro S. M. Rodrigues <maurosr@linux.vnet.ibm.com> +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +Reviewed-by: Christian Ehrhardt <christian.ehrhardt@canonical.com> +Tested-by: Christian Ehrhardt <christian.ehrhardt@canonical.com> +(cherry picked from commit 75a4ec42f70b5324f95d7ffbbfbf7457620735e4) + +https://bugzilla.redhat.com/1915183 + +Signed-off-by: Daniel Henrique Barboza <dbarboza@redhat.com> +Message-Id: <20210120000408.106596-1-dbarboza@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/util/virhostcpu.c | 2 +- + tests/virhostcputest.c | 21 ++++++++++++++++++--- + 2 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c +index 218272d7ec..37cc45e3a6 100644 +--- a/src/util/virhostcpu.c ++++ b/src/util/virhostcpu.c +@@ -855,7 +855,7 @@ virHostCPUGetStatsLinux(FILE *procstat, + _("Invalid cpuNum in %s"), + __FUNCTION__); + +- return 0; ++ return -1; + } + + +diff --git a/tests/virhostcputest.c b/tests/virhostcputest.c +index 7865b61578..70a723098b 100644 +--- a/tests/virhostcputest.c ++++ b/tests/virhostcputest.c +@@ -196,6 +196,7 @@ linuxTestHostCPU(const void *opaque) + struct nodeCPUStatsData { + const char *name; + int ncpus; ++ bool shouldFail; + }; + + static int +@@ -214,6 +215,19 @@ linuxTestNodeCPUStats(const void *data) + result = linuxCPUStatsCompareFiles(cpustatfile, + testData->ncpus, + outfile); ++ if (result < 0) { ++ if (testData->shouldFail) { ++ /* Expected error */ ++ result = 0; ++ } ++ } else { ++ if (testData->shouldFail) { ++ fprintf(stderr, "Expected a failure, got success"); ++ result = -1; ++ } ++ } ++ ++ + VIR_FREE(cpustatfile); + VIR_FREE(outfile); + return result; +@@ -258,14 +272,15 @@ mymain(void) + if (virTestRun(nodeData[i].testName, linuxTestHostCPU, &nodeData[i]) != 0) + ret = -1; + +-# define DO_TEST_CPU_STATS(name, ncpus) \ ++# define DO_TEST_CPU_STATS(name, ncpus, shouldFail) \ + do { \ +- static struct nodeCPUStatsData data = { name, ncpus }; \ ++ static struct nodeCPUStatsData data = { name, ncpus, shouldFail}; \ + if (virTestRun("CPU stats " name, linuxTestNodeCPUStats, &data) < 0) \ + ret = -1; \ + } while (0) + +- DO_TEST_CPU_STATS("24cpu", 24); ++ DO_TEST_CPU_STATS("24cpu", 24, false); ++ DO_TEST_CPU_STATS("24cpu", 25, true); + + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; + } +-- +2.30.0 + diff --git a/SOURCES/libvirt-virDomainNetFindIdx-add-support-for-CCW-addresses.patch b/SOURCES/libvirt-virDomainNetFindIdx-add-support-for-CCW-addresses.patch new file mode 100644 index 0000000..44beadb --- /dev/null +++ b/SOURCES/libvirt-virDomainNetFindIdx-add-support-for-CCW-addresses.patch @@ -0,0 +1,138 @@ +From 606da680fb4c7ee0f8a7ecc76057592433ea6ac9 Mon Sep 17 00:00:00 2001 +Message-Id: <606da680fb4c7ee0f8a7ecc76057592433ea6ac9@dist-git> +From: Cornelia Huck <cohuck@redhat.com> +Date: Fri, 2 Oct 2020 13:39:12 +0200 +Subject: [PATCH] virDomainNetFindIdx: add support for CCW addresses +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Allow to match with CCW addresses in addition to PCI addresses +(and MAC addresses). + +Signed-off-by: Cornelia Huck <cohuck@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +Signed-off-by: Ján Tomko <jtomko@redhat.com> +(cherry picked from commit 2fefbd03ab09f32b1b15d093096fa44870817751) + +https://bugzilla.redhat.com/show_bug.cgi?id=1837495 + +Signed-off-by: Ján Tomko <jtomko@redhat.com> +Message-Id: <a53fc421152b209c5a7fe69d4d5714a2f35077a8.1601638699.git.jtomko@redhat.com> +Acked-by: Cornelia Huck <cohuck@redhat.com> +--- + src/conf/device_conf.c | 12 ++++++++++++ + src/conf/device_conf.h | 3 +++ + src/conf/domain_conf.c | 23 ++++++++++++++++++++++- + src/libvirt_private.syms | 1 + + 4 files changed, 38 insertions(+), 1 deletion(-) + +diff --git a/src/conf/device_conf.c b/src/conf/device_conf.c +index 4dbd5c1ac9..9e96d08394 100644 +--- a/src/conf/device_conf.c ++++ b/src/conf/device_conf.c +@@ -370,6 +370,18 @@ virDomainDeviceCCWAddressParseXML(xmlNodePtr node, + return ret; + } + ++bool ++virDomainDeviceCCWAddressEqual(virDomainDeviceCCWAddressPtr addr1, ++ virDomainDeviceCCWAddressPtr addr2) ++{ ++ if (addr1->cssid == addr2->cssid && ++ addr1->ssid == addr2->ssid && ++ addr1->devno == addr2->devno) { ++ return true; ++ } ++ return false; ++} ++ + int + virDomainDeviceDriveAddressParseXML(xmlNodePtr node, + virDomainDeviceDriveAddressPtr addr) +diff --git a/src/conf/device_conf.h b/src/conf/device_conf.h +index e091d7cfe2..7a8227e743 100644 +--- a/src/conf/device_conf.h ++++ b/src/conf/device_conf.h +@@ -208,6 +208,9 @@ void virPCIDeviceAddressFormat(virBufferPtr buf, + bool virDomainDeviceCCWAddressIsValid(virDomainDeviceCCWAddressPtr addr); + int virDomainDeviceCCWAddressParseXML(xmlNodePtr node, + virDomainDeviceCCWAddressPtr addr); ++bool virDomainDeviceCCWAddressEqual(virDomainDeviceCCWAddressPtr addr1, ++ virDomainDeviceCCWAddressPtr addr2); ++#define VIR_CCW_DEVICE_ADDRESS_FMT "%x.%x.%04x" + + int virDomainDeviceDriveAddressParseXML(xmlNodePtr node, + virDomainDeviceDriveAddressPtr addr); +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 60962ee7c1..306926b64c 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -17385,6 +17385,8 @@ virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net) + bool MACAddrSpecified = !net->mac_generated; + bool PCIAddrSpecified = virDomainDeviceAddressIsValid(&net->info, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI); ++ bool CCWAddrSpecified = virDomainDeviceAddressIsValid(&net->info, ++ VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW); + + for (i = 0; i < def->nnets; i++) { + if (MACAddrSpecified && +@@ -17396,9 +17398,14 @@ virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net) + &net->info.addr.pci)) + continue; + ++ if (CCWAddrSpecified && ++ !virDomainDeviceCCWAddressEqual(&def->nets[i]->info.addr.ccw, ++ &net->info.addr.ccw)) ++ continue; ++ + if (matchidx >= 0) { + /* there were multiple matches on mac address, and no +- * qualifying guest-side PCI address was given, so we must ++ * qualifying guest-side PCI/CCW address was given, so we must + * fail (NB: a USB address isn't adequate, since it may + * specify only vendor and product ID, and there may be + * multiples of those. +@@ -17428,6 +17435,14 @@ virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net) + net->info.addr.pci.bus, + net->info.addr.pci.slot, + net->info.addr.pci.function); ++ } else if (MACAddrSpecified && CCWAddrSpecified) { ++ virReportError(VIR_ERR_DEVICE_MISSING, ++ _("no device matching MAC address %s found on " ++ VIR_CCW_DEVICE_ADDRESS_FMT), ++ virMacAddrFormat(&net->mac, mac), ++ net->info.addr.ccw.cssid, ++ net->info.addr.ccw.ssid, ++ net->info.addr.ccw.devno); + } else if (PCIAddrSpecified) { + virReportError(VIR_ERR_DEVICE_MISSING, + _("no device found on " VIR_PCI_DEVICE_ADDRESS_FMT), +@@ -17435,6 +17450,12 @@ virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net) + net->info.addr.pci.bus, + net->info.addr.pci.slot, + net->info.addr.pci.function); ++ } else if (CCWAddrSpecified) { ++ virReportError(VIR_ERR_DEVICE_MISSING, ++ _("no device found on " VIR_CCW_DEVICE_ADDRESS_FMT), ++ net->info.addr.ccw.cssid, ++ net->info.addr.ccw.ssid, ++ net->info.addr.ccw.devno); + } else if (MACAddrSpecified) { + virReportError(VIR_ERR_DEVICE_MISSING, + _("no device matching MAC address %s found"), +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 9e290c7bdf..130828706a 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -128,6 +128,7 @@ virDeviceInfoPCIAddressIsWanted; + virDomainDeviceAddressIsValid; + virDomainDeviceAddressTypeToString; + virDomainDeviceCcidAddressParseXML; ++virDomainDeviceCCWAddressEqual; + virDomainDeviceCCWAddressIsValid; + virDomainDeviceCCWAddressParseXML; + virDomainDeviceDriveAddressParseXML; +-- +2.28.0 + diff --git a/SOURCES/libvirt-vircgroup-correctly-free-nested-virCgroupPtr.patch b/SOURCES/libvirt-vircgroup-correctly-free-nested-virCgroupPtr.patch new file mode 100644 index 0000000..e72b84d --- /dev/null +++ b/SOURCES/libvirt-vircgroup-correctly-free-nested-virCgroupPtr.patch @@ -0,0 +1,45 @@ +From 7cdf83f2e699a9c9b8cafbc09dbd21d2cb3a3b45 Mon Sep 17 00:00:00 2001 +Message-Id: <7cdf83f2e699a9c9b8cafbc09dbd21d2cb3a3b45@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Fri, 19 Feb 2021 13:34:01 +0100 +Subject: [PATCH] vircgroup: correctly free nested virCgroupPtr +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixes: 184245f53b94fc84f727eb6e8a2aa52df02d69c0 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit 6a1f5e8a4f3184bb54b9dcaa3afcf8c97adccb62) + +Conflicts: + src/util/vircgroup.c + - missing upstream g_free rewrite + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <bc2f0207bc684ca81c45b6234a7aaba5227867d7.1613737828.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/util/vircgroup.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index d0f867ba7f..0a6404e97c 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -3711,7 +3711,8 @@ virCgroupFree(virCgroupPtr *group) + VIR_FREE((*group)->unified.mountPoint); + VIR_FREE((*group)->unified.placement); + VIR_FREE((*group)->unitName); +- VIR_FREE((*group)->nested); ++ ++ virCgroupFree(&(*group)->nested); + + VIR_FREE((*group)->path); + VIR_FREE(*group); +-- +2.30.0 + diff --git a/SOURCES/libvirt-vircgroup-enforce-range-limit-for-cpu.shares.patch b/SOURCES/libvirt-vircgroup-enforce-range-limit-for-cpu.shares.patch new file mode 100644 index 0000000..d800b77 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-enforce-range-limit-for-cpu.shares.patch @@ -0,0 +1,147 @@ +From c82c32f60579d148f37064e5156e857fa3c84c2f Mon Sep 17 00:00:00 2001 +Message-Id: <c82c32f60579d148f37064e5156e857fa3c84c2f@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Thu, 4 Mar 2021 12:57:57 +0100 +Subject: [PATCH] vircgroup: enforce range limit for cpu.shares +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Before the conversion to using systemd DBus API to set the cpu.shares +there was some magic conversion done by kernel which was documented in +virsh manpage as well. Now systemd errors out if the value is out of +range. + +Since we enforce the range for other cpu cgroup attributes 'quota' and +'period' it makes sense to do the same for 'shares' as well. + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit 1d9d9961ada6c2d0b9facae0ef8be4f459cf7fc9) + +Conflicts: + docs/formatdomain.rst + src/conf/domain_validate.c + - both are not present in downstream + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <79b9ef9f98b3ab35061f8c4e4acf7b6861d28055.1614858616.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + docs/formatdomain.html.in | 1 + + docs/manpages/virsh.rst | 5 +---- + src/conf/domain_conf.c | 10 ++++++++++ + src/util/vircgroup.h | 2 ++ + src/util/vircgroupv1.c | 10 ++++++++++ + src/util/vircgroupv2.c | 10 ++++++++++ + 6 files changed, 34 insertions(+), 4 deletions(-) + +diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in +index 4341e256a8..7ac9523684 100644 +--- a/docs/formatdomain.html.in ++++ b/docs/formatdomain.html.in +@@ -854,6 +854,7 @@ + it's a relative measure based on the setting of other VM, + e.g. A VM configured with value + 2048 will get twice as much CPU time as a VM configured with value 1024. ++ The value should be in range [2, 262144]. + <span class="since">Since 0.9.0</span> + </dd> + <dt><code>period</code></dt> +diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst +index a5b95c1123..01e1c01912 100644 +--- a/docs/manpages/virsh.rst ++++ b/docs/manpages/virsh.rst +@@ -3704,10 +3704,7 @@ If *--live* is specified, set scheduler information of a running guest. + If *--config* is specified, affect the next boot of a persistent guest. + If *--current* is specified, affect the current guest state. + +-``Note``: The cpu_shares parameter has a valid value range of 0-262144; Negative +-values are wrapped to positive, and larger values are capped at the maximum. +-Therefore, -1 is a useful shorthand for 262144. On the Linux kernel, the +-values 0 and 1 are automatically converted to a minimal value of 2. ++``Note``: The cpu_shares parameter has a valid value range of 2-262144. + + ``Note``: The weight and cap parameters are defined only for the + XEN_CREDIT scheduler. +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 9f6cdb0de8..444657c9a1 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -7026,6 +7026,16 @@ virDomainDefLifecycleActionValidate(const virDomainDef *def) + static int + virDomainDefCputuneValidate(const virDomainDef *def) + { ++ if (def->cputune.shares > 0 && ++ (def->cputune.shares < VIR_CGROUP_CPU_SHARES_MIN || ++ def->cputune.shares > VIR_CGROUP_CPU_SHARES_MAX)) { ++ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, ++ _("Value of cputune 'shares' must be in range [%llu, %llu]"), ++ VIR_CGROUP_CPU_SHARES_MIN, ++ VIR_CGROUP_CPU_SHARES_MAX); ++ return -1; ++ } ++ + CPUTUNE_VALIDATE_PERIOD(period); + CPUTUNE_VALIDATE_PERIOD(global_period); + CPUTUNE_VALIDATE_PERIOD(emulator_period); +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index 1c6edea0be..938cfdfbe3 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -243,6 +243,8 @@ virCgroupGetDomainTotalCpuStats(virCgroupPtr group, + int virCgroupSetCpuShares(virCgroupPtr group, unsigned long long shares); + int virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares); + ++#define VIR_CGROUP_CPU_SHARES_MIN 2LL ++#define VIR_CGROUP_CPU_SHARES_MAX 262144LL + #define VIR_CGROUP_CPU_PERIOD_MIN 1000LL + #define VIR_CGROUP_CPU_PERIOD_MAX 1000000LL + #define VIR_CGROUP_CPU_QUOTA_MIN 1000LL +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 49a2cb023e..d417446447 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1901,6 +1901,16 @@ static int + virCgroupV1SetCpuShares(virCgroupPtr group, + unsigned long long shares) + { ++ if (shares < VIR_CGROUP_CPU_SHARES_MIN || ++ shares > VIR_CGROUP_CPU_SHARES_MAX) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ _("shares '%llu' must be in range [%llu, %llu]"), ++ shares, ++ VIR_CGROUP_CPU_SHARES_MIN, ++ VIR_CGROUP_CPU_SHARES_MAX); ++ return -1; ++ } ++ + if (group->unitName) { + return virCgroupSetValueDBus(group->unitName, "CPUShares", + "t", shares); +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index a14fc669fb..079fe6a8ec 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1499,6 +1499,16 @@ static int + virCgroupV2SetCpuShares(virCgroupPtr group, + unsigned long long shares) + { ++ if (shares < VIR_CGROUP_CPU_SHARES_MIN || ++ shares > VIR_CGROUP_CPU_SHARES_MAX) { ++ virReportError(VIR_ERR_INVALID_ARG, ++ _("shares '%llu' must be in range [%llu, %llu]"), ++ shares, ++ VIR_CGROUP_CPU_SHARES_MIN, ++ VIR_CGROUP_CPU_SHARES_MAX); ++ return -1; ++ } ++ + if (group->unitName) { + return virCgroupSetValueDBus(group->unitName, "CPUWeight", + "t", shares); +-- +2.30.0 + diff --git a/SOURCES/libvirt-vircgroup-fix-cpu-quota-maximum-limit.patch b/SOURCES/libvirt-vircgroup-fix-cpu-quota-maximum-limit.patch new file mode 100644 index 0000000..c744ed7 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-fix-cpu-quota-maximum-limit.patch @@ -0,0 +1,45 @@ +From 92b7a56b1a23d1cf39e810a58a6d7d0b1f500e69 Mon Sep 17 00:00:00 2001 +Message-Id: <92b7a56b1a23d1cf39e810a58a6d7d0b1f500e69@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Thu, 21 Jan 2021 10:24:06 -0300 +Subject: [PATCH] vircgroup: fix cpu quota maximum limit + +Kernel commit <d505b8af58912ae1e1a211fabc9995b19bd40828> added proper +check for cpu quota maximum limit to prevent internal overflow. + +Even though this change is not present in all kernels it makes sense +to enforce the same limit in libvirt. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1750315 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit ed1ba69f5a8132f8c1e73d2a1f142d70de0b564a) + +https://bugzilla.redhat.com/1915733 + +Signed-off-by: Daniel Henrique Barboza <dbarboza@redhat.com> +Message-Id: <20210121132406.337681-5-dbarboza@redhat.com> +Reviewed-by: Pavel Hrdina <phrdina@redhat.com> +--- + src/util/vircgroup.h | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index 83fa74840f..1c6edea0be 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -246,7 +246,9 @@ int virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares); + #define VIR_CGROUP_CPU_PERIOD_MIN 1000LL + #define VIR_CGROUP_CPU_PERIOD_MAX 1000000LL + #define VIR_CGROUP_CPU_QUOTA_MIN 1000LL +-#define VIR_CGROUP_CPU_QUOTA_MAX 18446744073709551LL ++/* Based on kernel code ((1ULL << MAX_BW_BITS) - 1) where MAX_BW_BITS is ++ * (64 - BW_SHIFT) and BW_SHIFT is 20 */ ++#define VIR_CGROUP_CPU_QUOTA_MAX 17592186044415LL + + int virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period); + int virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period); +-- +2.30.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-nested-cgroup-to-properly-work-with-systemd.patch b/SOURCES/libvirt-vircgroup-introduce-nested-cgroup-to-properly-work-with-systemd.patch new file mode 100644 index 0000000..435dc6a --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-nested-cgroup-to-properly-work-with-systemd.patch @@ -0,0 +1,879 @@ +From 2593f2e4626fbb6dfef2317bceea4d1b8275f9d8 Mon Sep 17 00:00:00 2001 +Message-Id: <2593f2e4626fbb6dfef2317bceea4d1b8275f9d8@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Fri, 19 Feb 2021 13:33:59 +0100 +Subject: [PATCH] vircgroup: introduce nested cgroup to properly work with + systemd +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When running on host with systemd we register VMs with machined. +In this case systemd creates the root VM cgroup for us. This has some +implications where one of them is that systemd owns all files inside +the root VM cgroup and we should not touch them. + +We already use DBus calls for some of the APIs but for the remaining +ones we will continue accessing the files directly. Systemd doesn't +support threaded cgroups so we need to do this. + +The reason why we don't use DBus for most of the APIs is that we already +have a code that works with files and we would have to check if systemd +supports each API. + +This change introduces new topology on systemd hosts: + +$ROOT + | + +- machine.slice + | + +- machine-qemu\x2d1\x2dvm1.scope + | + +- libvirt + | + +- emulator + +- vcpu0 + +- vcpu0 + +compared to the previous topology: + +$ROOT + | + +- machine.slice + | + +- machine-qemu\x2d1\x2dvm1.scope + | + +- emulator + +- vcpu0 + +- vcpu0 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit 184245f53b94fc84f727eb6e8a2aa52df02d69c0) + +Conflicts: + src/util/vircgroup.c + - missing upstream g_free and g_autofree rewrite + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <51312c8b520e4ed794f8cd8a77b77c228387bb15.1613737828.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + docs/cgroups.html.in | 29 +++-- + src/util/vircgroup.c | 256 +++++++++++++++++++++++++++++++-------- + src/util/vircgrouppriv.h | 4 + + src/util/vircgroupv1.c | 15 ++- + src/util/vircgroupv2.c | 6 + + 5 files changed, 245 insertions(+), 65 deletions(-) + +diff --git a/docs/cgroups.html.in b/docs/cgroups.html.in +index 78dede1bba..412a9360ff 100644 +--- a/docs/cgroups.html.in ++++ b/docs/cgroups.html.in +@@ -117,21 +117,27 @@ $ROOT + | + +- machine-qemu\x2d1\x2dvm1.scope + | | +- | +- emulator +- | +- vcpu0 +- | +- vcpu1 ++ | +- libvirt ++ | | ++ | +- emulator ++ | +- vcpu0 ++ | +- vcpu1 + | + +- machine-qemu\x2d2\x2dvm2.scope + | | +- | +- emulator +- | +- vcpu0 +- | +- vcpu1 ++ | +- libvirt ++ | | ++ | +- emulator ++ | +- vcpu0 ++ | +- vcpu1 + | + +- machine-qemu\x2d3\x2dvm3.scope + | | +- | +- emulator +- | +- vcpu0 +- | +- vcpu1 ++ | +- libvirt ++ | | ++ | +- emulator ++ | +- vcpu0 ++ | +- vcpu1 + | + +- machine-engineering.slice + | | +@@ -148,6 +154,11 @@ $ROOT + +- machine-lxc\x2d33333\x2dcontainer3.scope + </pre> + ++ <p> ++ Prior libvirt 7.1.0 the topology doesn't have extra ++ <code>libvirt</code> directory. ++ </p> ++ + <h3><a id="currentLayoutGeneric">Non-systemd cgroups layout</a></h3> + + <p> +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 8f5bcd94f4..d0f867ba7f 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -639,6 +639,22 @@ virCgroupMakeGroup(virCgroupPtr parent, + } + + ++static bool ++virCgroupExists(virCgroupPtr group) ++{ ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { ++ if (group->backends[i] && ++ !group->backends[i]->exists(group)) { ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++ + /** + * virCgroupNew: + * @path: path for the new group +@@ -695,10 +711,11 @@ virCgroupAddTaskInternal(virCgroupPtr group, + unsigned int flags) + { + size_t i; ++ virCgroupPtr parent = virCgroupGetNested(group); + + for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { +- if (group->backends[i] && +- group->backends[i]->addTask(group, pid, flags) < 0) { ++ if (parent->backends[i] && ++ parent->backends[i]->addTask(parent, pid, flags) < 0) { + return -1; + } + } +@@ -871,6 +888,30 @@ virCgroupNewPartition(const char *path, + } + + ++static int ++virCgroupNewNested(virCgroupPtr parent, ++ int controllers, ++ bool create, ++ pid_t pid, ++ virCgroupPtr *nested) ++{ ++ virCgroupPtr new = NULL; ++ ++ if (virCgroupNew(-1, "libvirt", parent, controllers, &new) < 0) ++ return -1; ++ ++ if (create) { ++ if (virCgroupMakeGroup(parent, new, create, pid, VIR_CGROUP_NONE) < 0) { ++ virCgroupFree(&new); ++ return -1; ++ } ++ } ++ ++ *nested = g_steal_pointer(&new); ++ return 0; ++} ++ ++ + /** + * virCgroupNewSelf: + * +@@ -954,6 +995,7 @@ virCgroupNewThread(virCgroupPtr domain, + virCgroupPtr *group) + { + g_autofree char *name = NULL; ++ virCgroupPtr parent = NULL; + int controllers; + + switch (nameval) { +@@ -976,10 +1018,12 @@ virCgroupNewThread(virCgroupPtr domain, + (1 << VIR_CGROUP_CONTROLLER_CPUACCT) | + (1 << VIR_CGROUP_CONTROLLER_CPUSET)); + +- if (virCgroupNew(-1, name, domain, controllers, group) < 0) ++ parent = virCgroupGetNested(domain); ++ ++ if (virCgroupNew(-1, name, parent, controllers, group) < 0) + return -1; + +- if (virCgroupMakeGroup(domain, *group, create, -1, VIR_CGROUP_THREAD) < 0) { ++ if (virCgroupMakeGroup(parent, *group, create, -1, VIR_CGROUP_THREAD) < 0) { + virCgroupFree(group); + return -1; + } +@@ -1009,6 +1053,7 @@ virCgroupNewDetectMachine(const char *name, + virCgroupPtr *group) + { + size_t i; ++ virCgroupPtr nested = NULL; + + if (virCgroupNewDetect(pid, controllers, group) < 0) { + if (virCgroupNewIgnoreError()) +@@ -1032,6 +1077,14 @@ virCgroupNewDetectMachine(const char *name, + if (virSystemdHasMachined() == 0 && !(*group)->unitName) + return -1; + ++ if (virCgroupNewNested((*group), controllers, false, -1, &nested) < 0) ++ return -1; ++ ++ if (virCgroupExists(nested)) ++ (*group)->nested = g_steal_pointer(&nested); ++ ++ virCgroupFree(&nested); ++ + return 0; + } + +@@ -1107,6 +1160,7 @@ virCgroupNewMachineSystemd(const char *name, + { + int rv; + virCgroupPtr init; ++ virCgroupPtr nested = NULL; + g_autofree char *path = NULL; + size_t i; + +@@ -1157,6 +1211,13 @@ virCgroupNewMachineSystemd(const char *name, + return -1; + } + ++ if (virCgroupNewNested((*group), controllers, true, pidleader, &nested) < 0) { ++ virCgroupFree(group); ++ return -1; ++ } ++ ++ (*group)->nested = nested; ++ + if (virCgroupAddProcess(*group, pidleader) < 0) { + virErrorPtr saved; + +@@ -1349,7 +1410,9 @@ virCgroupGetBlkioIoServiced(virCgroupPtr group, + long long *requests_read, + long long *requests_write) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO, + getBlkioIoServiced, -1, + bytes_read, bytes_write, + requests_read, requests_write); +@@ -1376,7 +1439,9 @@ virCgroupGetBlkioIoDeviceServiced(virCgroupPtr group, + long long *requests_read, + long long *requests_write) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO, + getBlkioIoDeviceServiced, -1, + path, bytes_read, bytes_write, + requests_read, requests_write); +@@ -1427,7 +1492,9 @@ virCgroupSetBlkioDeviceReadIops(virCgroupPtr group, + const char *path, + unsigned int riops) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO, + setBlkioDeviceReadIops, -1, path, riops); + } + +@@ -1445,7 +1512,9 @@ virCgroupSetBlkioDeviceWriteIops(virCgroupPtr group, + const char *path, + unsigned int wiops) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO, + setBlkioDeviceWriteIops, -1, path, wiops); + } + +@@ -1463,7 +1532,9 @@ virCgroupSetBlkioDeviceReadBps(virCgroupPtr group, + const char *path, + unsigned long long rbps) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO, + setBlkioDeviceReadBps, -1, path, rbps); + } + +@@ -1480,7 +1551,9 @@ virCgroupSetBlkioDeviceWriteBps(virCgroupPtr group, + const char *path, + unsigned long long wbps) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO, + setBlkioDeviceWriteBps, -1, path, wbps); + } + +@@ -1516,7 +1589,9 @@ virCgroupGetBlkioDeviceReadIops(virCgroupPtr group, + const char *path, + unsigned int *riops) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO, + getBlkioDeviceReadIops, -1, path, riops); + } + +@@ -1533,7 +1608,9 @@ virCgroupGetBlkioDeviceWriteIops(virCgroupPtr group, + const char *path, + unsigned int *wiops) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO, + getBlkioDeviceWriteIops, -1, path, wiops); + } + +@@ -1550,7 +1627,9 @@ virCgroupGetBlkioDeviceReadBps(virCgroupPtr group, + const char *path, + unsigned long long *rbps) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO, + getBlkioDeviceReadBps, -1, path, rbps); + } + +@@ -1567,7 +1646,9 @@ virCgroupGetBlkioDeviceWriteBps(virCgroupPtr group, + const char *path, + unsigned long long *wbps) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_BLKIO, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_BLKIO, + getBlkioDeviceWriteBps, -1, path, wbps); + } + +@@ -1600,7 +1681,9 @@ virCgroupGetBlkioDeviceWeight(virCgroupPtr group, + int + virCgroupSetMemory(virCgroupPtr group, unsigned long long kb) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY, + setMemory, -1, kb); + } + +@@ -1627,7 +1710,9 @@ virCgroupGetMemoryStat(virCgroupPtr group, + unsigned long long *inactiveFile, + unsigned long long *unevictable) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY, + getMemoryStat, -1, cache, + activeAnon, inactiveAnon, + activeFile, inactiveFile, +@@ -1646,7 +1731,9 @@ virCgroupGetMemoryStat(virCgroupPtr group, + int + virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY, + getMemoryUsage, -1, kb); + } + +@@ -1662,7 +1749,9 @@ virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb) + int + virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY, + setMemoryHardLimit, -1, kb); + } + +@@ -1678,7 +1767,9 @@ virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb) + int + virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY, + getMemoryHardLimit, -1, kb); + } + +@@ -1694,7 +1785,9 @@ virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb) + int + virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY, + setMemorySoftLimit, -1, kb); + } + +@@ -1710,7 +1803,9 @@ virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb) + int + virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY, + getMemorySoftLimit, -1, kb); + } + +@@ -1726,7 +1821,9 @@ virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb) + int + virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY, + setMemSwapHardLimit, -1, kb); + } + +@@ -1742,7 +1839,9 @@ virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb) + int + virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY, + getMemSwapHardLimit, -1, kb); + } + +@@ -1758,7 +1857,9 @@ virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb) + int + virCgroupGetMemSwapUsage(virCgroupPtr group, unsigned long long *kb) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_MEMORY, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_MEMORY, + getMemSwapUsage, -1, kb); + } + +@@ -1774,7 +1875,9 @@ virCgroupGetMemSwapUsage(virCgroupPtr group, unsigned long long *kb) + int + virCgroupSetCpusetMems(virCgroupPtr group, const char *mems) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUSET, + setCpusetMems, -1, mems); + } + +@@ -1790,7 +1893,9 @@ virCgroupSetCpusetMems(virCgroupPtr group, const char *mems) + int + virCgroupGetCpusetMems(virCgroupPtr group, char **mems) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUSET, + getCpusetMems, -1, mems); + } + +@@ -1806,7 +1911,9 @@ virCgroupGetCpusetMems(virCgroupPtr group, char **mems) + int + virCgroupSetCpusetMemoryMigrate(virCgroupPtr group, bool migrate) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUSET, + setCpusetMemoryMigrate, -1, migrate); + } + +@@ -1822,7 +1929,9 @@ virCgroupSetCpusetMemoryMigrate(virCgroupPtr group, bool migrate) + int + virCgroupGetCpusetMemoryMigrate(virCgroupPtr group, bool *migrate) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUSET, + getCpusetMemoryMigrate, -1, migrate); + } + +@@ -1838,7 +1947,9 @@ virCgroupGetCpusetMemoryMigrate(virCgroupPtr group, bool *migrate) + int + virCgroupSetCpusetCpus(virCgroupPtr group, const char *cpus) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUSET, + setCpusetCpus, -1, cpus); + } + +@@ -1854,7 +1965,9 @@ virCgroupSetCpusetCpus(virCgroupPtr group, const char *cpus) + int + virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUSET, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUSET, + getCpusetCpus, -1, cpus); + } + +@@ -1869,7 +1982,9 @@ virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus) + int + virCgroupDenyAllDevices(virCgroupPtr group) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_DEVICES, + denyAllDevices, -1); + } + +@@ -1890,7 +2005,9 @@ virCgroupDenyAllDevices(virCgroupPtr group) + int + virCgroupAllowAllDevices(virCgroupPtr group, int perms) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_DEVICES, + allowAllDevices, -1, perms); + } + +@@ -1910,7 +2027,9 @@ int + virCgroupAllowDevice(virCgroupPtr group, char type, int major, int minor, + int perms) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_DEVICES, + allowDevice, -1, type, major, minor, perms); + } + +@@ -1936,6 +2055,7 @@ virCgroupAllowDevicePath(virCgroupPtr group, + bool ignoreEacces) + { + struct stat sb; ++ virCgroupPtr parent = virCgroupGetNested(group); + + if (stat(path, &sb) < 0) { + if (errno == EACCES && ignoreEacces) +@@ -1950,7 +2070,7 @@ virCgroupAllowDevicePath(virCgroupPtr group, + if (!S_ISCHR(sb.st_mode) && !S_ISBLK(sb.st_mode)) + return 1; + +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES, ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_DEVICES, + allowDevice, -1, + S_ISCHR(sb.st_mode) ? 'c' : 'b', + major(sb.st_rdev), +@@ -1974,7 +2094,9 @@ int + virCgroupDenyDevice(virCgroupPtr group, char type, int major, int minor, + int perms) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_DEVICES, + denyDevice, -1, type, major, minor, perms); + } + +@@ -2000,6 +2122,7 @@ virCgroupDenyDevicePath(virCgroupPtr group, + bool ignoreEacces) + { + struct stat sb; ++ virCgroupPtr parent = virCgroupGetNested(group); + + if (stat(path, &sb) < 0) { + if (errno == EACCES && ignoreEacces) +@@ -2014,7 +2137,7 @@ virCgroupDenyDevicePath(virCgroupPtr group, + if (!S_ISCHR(sb.st_mode) && !S_ISBLK(sb.st_mode)) + return 1; + +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_DEVICES, ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_DEVICES, + denyDevice, -1, + S_ISCHR(sb.st_mode) ? 'c' : 'b', + major(sb.st_rdev), +@@ -2282,7 +2405,9 @@ virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares) + int + virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPU, + setCpuCfsPeriod, -1, cfs_period); + } + +@@ -2298,7 +2423,9 @@ virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period) + int + virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPU, + getCpuCfsPeriod, -1, cfs_period); + } + +@@ -2315,7 +2442,9 @@ virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period) + int + virCgroupSetCpuCfsQuota(virCgroupPtr group, long long cfs_quota) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPU, + setCpuCfsQuota, -1, cfs_quota); + } + +@@ -2323,7 +2452,9 @@ virCgroupSetCpuCfsQuota(virCgroupPtr group, long long cfs_quota) + int + virCgroupGetCpuacctPercpuUsage(virCgroupPtr group, char **usage) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUACCT, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUACCT, + getCpuacctPercpuUsage, -1, usage); + } + +@@ -2669,7 +2800,9 @@ virCgroupKillPainfully(virCgroupPtr group) + int + virCgroupGetCpuCfsQuota(virCgroupPtr group, long long *cfs_quota) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPU, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPU, + getCpuCfsQuota, -1, cfs_quota); + } + +@@ -2677,7 +2810,9 @@ virCgroupGetCpuCfsQuota(virCgroupPtr group, long long *cfs_quota) + int + virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUACCT, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUACCT, + getCpuacctUsage, -1, usage); + } + +@@ -2686,7 +2821,9 @@ int + virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user, + unsigned long long *sys) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_CPUACCT, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPUACCT, + getCpuacctStat, -1, user, sys); + } + +@@ -2694,7 +2831,9 @@ virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user, + int + virCgroupSetFreezerState(virCgroupPtr group, const char *state) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_FREEZER, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_FREEZER, + setFreezerState, -1, state); + } + +@@ -2702,7 +2841,9 @@ virCgroupSetFreezerState(virCgroupPtr group, const char *state) + int + virCgroupGetFreezerState(virCgroupPtr group, char **state) + { +- VIR_CGROUP_BACKEND_CALL(group, VIR_CGROUP_CONTROLLER_FREEZER, ++ virCgroupPtr parent = virCgroupGetNested(group); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_FREEZER, + getFreezerState, -1, state); + } + +@@ -2712,10 +2853,11 @@ virCgroupBindMount(virCgroupPtr group, const char *oldroot, + const char *mountopts) + { + size_t i; ++ virCgroupPtr parent = virCgroupGetNested(group); + + for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { +- if (group->backends[i] && +- group->backends[i]->bindMount(group, oldroot, mountopts) < 0) { ++ if (parent->backends[i] && ++ parent->backends[i]->bindMount(parent, oldroot, mountopts) < 0) { + return -1; + } + } +@@ -2730,10 +2872,11 @@ int virCgroupSetOwner(virCgroupPtr cgroup, + int controllers) + { + size_t i; ++ virCgroupPtr parent = virCgroupGetNested(cgroup); + + for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { +- if (cgroup->backends[i] && +- cgroup->backends[i]->setOwner(cgroup, uid, gid, controllers) < 0) { ++ if (parent->backends[i] && ++ parent->backends[i]->setOwner(parent, uid, gid, controllers) < 0) { + return -1; + } + } +@@ -2752,7 +2895,9 @@ int virCgroupSetOwner(virCgroupPtr cgroup, + bool + virCgroupSupportsCpuBW(virCgroupPtr cgroup) + { +- VIR_CGROUP_BACKEND_CALL(cgroup, VIR_CGROUP_CONTROLLER_CPU, ++ virCgroupPtr parent = virCgroupGetNested(cgroup); ++ ++ VIR_CGROUP_BACKEND_CALL(parent, VIR_CGROUP_CONTROLLER_CPU, + supportsCpuBW, false); + } + +@@ -2760,10 +2905,11 @@ int + virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller) + { + size_t i; ++ virCgroupPtr parent = virCgroupGetNested(cgroup); + + for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { +- if (cgroup->backends[i]) { +- int rc = cgroup->backends[i]->hasEmptyTasks(cgroup, controller); ++ if (parent->backends[i]) { ++ int rc = parent->backends[i]->hasEmptyTasks(parent, controller); + if (rc <= 0) + return rc; + } +@@ -3565,6 +3711,7 @@ virCgroupFree(virCgroupPtr *group) + VIR_FREE((*group)->unified.mountPoint); + VIR_FREE((*group)->unified.placement); + VIR_FREE((*group)->unitName); ++ VIR_FREE((*group)->nested); + + VIR_FREE((*group)->path); + VIR_FREE(*group); +@@ -3577,9 +3724,12 @@ virCgroupDelThread(virCgroupPtr cgroup, + int idx) + { + virCgroupPtr new_cgroup = NULL; ++ virCgroupPtr parent = NULL; + + if (cgroup) { +- if (virCgroupNewThread(cgroup, nameval, idx, false, &new_cgroup) < 0) ++ parent = virCgroupGetNested(cgroup); ++ ++ if (virCgroupNewThread(parent, nameval, idx, false, &new_cgroup) < 0) + return -1; + + /* Remove the offlined cgroup */ +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index b4a9e0b379..104d74e4d7 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -69,8 +69,12 @@ struct _virCgroup { + virCgroupV2Controller unified; + + char *unitName; ++ virCgroupPtr nested; + }; + ++#define virCgroupGetNested(cgroup) \ ++ (cgroup->nested ? cgroup->nested : cgroup) ++ + #define virCgroupSetValueDBus(unitName, key, ...) \ + ({ \ + int __ret = -1; \ +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 57d617cb69..49a2cb023e 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -338,6 +338,8 @@ virCgroupV1DetectPlacement(virCgroupPtr group, + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + const char *typestr = virCgroupV1ControllerTypeToString(i); ++ g_autofree char* placement = NULL; ++ char *tmp = NULL; + + if (!virCgroupV1MountOptsMatchController(controllers, typestr)) + continue; +@@ -348,17 +350,24 @@ virCgroupV1DetectPlacement(virCgroupPtr group, + if (group->legacy[i].placement) + continue; + ++ /* On systemd we create a nested cgroup for some cgroup tasks ++ * but the placement should point to the root cgroup. */ ++ placement = g_strdup(selfpath); ++ tmp = g_strrstr(placement, "/libvirt"); ++ if (tmp) ++ *tmp = '\0'; ++ + /* + * selfpath == "/" + path="" -> "/" + * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service" + * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo" + */ + if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) { +- group->legacy[i].placement = g_strdup(selfpath); ++ group->legacy[i].placement = g_strdup(placement); + } else { +- bool delim = STREQ(selfpath, "/") || STREQ(path, ""); ++ bool delim = STREQ(placement, "/") || STREQ(path, ""); + +- group->legacy[i].placement = g_strdup_printf("%s%s%s", selfpath, ++ group->legacy[i].placement = g_strdup_printf("%s%s%s", placement, + delim ? "" : "/", + path); + } +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index d15e2354cf..a14fc669fb 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -210,6 +210,12 @@ virCgroupV2DetectPlacement(virCgroupPtr group, + if (tmp) + *tmp = '\0'; + ++ /* On systemd we create a nested cgroup for some cgroup tasks ++ * but the placement should point to the root cgroup. */ ++ tmp = g_strrstr(placement, "/libvirt"); ++ if (tmp) ++ *tmp = '\0'; ++ + /* + * selfpath == "/" + path="" -> "/" + * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service" +-- +2.30.0 + diff --git a/SOURCES/libvirt-vircgroup-introduce-virCgroupV1Exists-and-virCgroupV2Exists.patch b/SOURCES/libvirt-vircgroup-introduce-virCgroupV1Exists-and-virCgroupV2Exists.patch new file mode 100644 index 0000000..c73bf43 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-introduce-virCgroupV1Exists-and-virCgroupV2Exists.patch @@ -0,0 +1,129 @@ +From f835b834d7922bed1ccda35885e42ab7c3f4a70f Mon Sep 17 00:00:00 2001 +Message-Id: <f835b834d7922bed1ccda35885e42ab7c3f4a70f@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Fri, 19 Feb 2021 13:33:58 +0100 +Subject: [PATCH] vircgroup: introduce virCgroupV1Exists and virCgroupV2Exists +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This will check if the cgroup actually exists on the system. + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit badc2bcc7398d8c0a739998a80411ddebf129512) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <14297ed923f0f23cc52506e61e637c8f45e331ee.1613737828.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/util/vircgroupbackend.h | 4 ++++ + src/util/vircgroupv1.c | 27 +++++++++++++++++++++++++++ + src/util/vircgroupv2.c | 15 +++++++++++++++ + 3 files changed, 46 insertions(+) + +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index ac7b3ae517..dabc7bd4b4 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -115,6 +115,9 @@ typedef int + const char *key, + char **path); + ++typedef bool ++(*virCgroupExistsCB)(virCgroupPtr group); ++ + typedef int + (*virCgroupMakeGroupCB)(virCgroupPtr parent, + virCgroupPtr group, +@@ -378,6 +381,7 @@ struct _virCgroupBackend { + virCgroupGetAnyControllerCB getAnyController; + virCgroupPathOfControllerCB pathOfController; + virCgroupMakeGroupCB makeGroup; ++ virCgroupExistsCB exists; + virCgroupRemoveCB remove; + virCgroupAddTaskCB addTask; + virCgroupHasEmptyTasksCB hasEmptyTasks; +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index eb2b611cee..57d617cb69 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -670,6 +670,32 @@ virCgroupV1MakeGroup(virCgroupPtr parent, + } + + ++static bool ++virCgroupV1Exists(virCgroupPtr group) ++{ ++ size_t i; ++ ++ for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { ++ g_autofree char *path = NULL; ++ ++ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) ++ continue; ++ ++ if (!group->legacy[i].mountPoint) ++ continue; ++ ++ if (virCgroupV1PathOfController(group, i, "", &path) < 0) ++ return false; ++ ++ if (!virFileExists(path)) { ++ return false; ++ } ++ } ++ ++ return true; ++} ++ ++ + static int + virCgroupV1Remove(virCgroupPtr group) + { +@@ -2136,6 +2162,7 @@ virCgroupBackend virCgroupV1Backend = { + .getAnyController = virCgroupV1GetAnyController, + .pathOfController = virCgroupV1PathOfController, + .makeGroup = virCgroupV1MakeGroup, ++ .exists = virCgroupV1Exists, + .remove = virCgroupV1Remove, + .addTask = virCgroupV1AddTask, + .hasEmptyTasks = virCgroupV1HasEmptyTasks, +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 5e19ed8332..d15e2354cf 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -493,6 +493,20 @@ virCgroupV2MakeGroup(virCgroupPtr parent, + } + + ++static bool ++virCgroupV2Exists(virCgroupPtr group) ++{ ++ g_autofree char *path = NULL; ++ int controller; ++ ++ controller = virCgroupV2GetAnyController(group); ++ if (virCgroupV2PathOfController(group, controller, "", &path) < 0) ++ return false; ++ ++ return virFileExists(path); ++} ++ ++ + static int + virCgroupV2Remove(virCgroupPtr group) + { +@@ -1886,6 +1900,7 @@ virCgroupBackend virCgroupV2Backend = { + .getAnyController = virCgroupV2GetAnyController, + .pathOfController = virCgroupV2PathOfController, + .makeGroup = virCgroupV2MakeGroup, ++ .exists = virCgroupV2Exists, + .remove = virCgroupV2Remove, + .addTask = virCgroupV2AddTask, + .hasEmptyTasks = virCgroupV2HasEmptyTasks, +-- +2.30.0 + diff --git a/SOURCES/libvirt-vircgroup-use-DBus-call-to-systemd-for-some-APIs.patch b/SOURCES/libvirt-vircgroup-use-DBus-call-to-systemd-for-some-APIs.patch new file mode 100644 index 0000000..8d300b3 --- /dev/null +++ b/SOURCES/libvirt-vircgroup-use-DBus-call-to-systemd-for-some-APIs.patch @@ -0,0 +1,310 @@ +From 205289d2792aacf68ed2cb8563d1860bd36137a0 Mon Sep 17 00:00:00 2001 +Message-Id: <205289d2792aacf68ed2cb8563d1860bd36137a0@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Fri, 19 Feb 2021 13:33:55 +0100 +Subject: [PATCH] vircgroup: use DBus call to systemd for some APIs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When running on host with systemd we register VMs with machined. +In this case systemd creates the root VM cgroup for us. This has some +implications where one of them is that systemd owns all files inside +the root VM cgroup and we should not touch them. + +If we change any value in file that systemd knows about it will be +changed to what systemd thinks it should be when executing +`systemctl daemon-reload`. + +These are the APIs that we need to call using systemd because they set +limits that are proportional to sibling cgroups. + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit 9c1693eff427661616ce1bd2795688f87288a412) + +Conflicts: + src/util/vircgroup.c + - missing upstream g_autofree rewrite + - missing upstream glib dbus rewrite, hence the ugly macro + instead of a function + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <5d22d307112333f1da565cb642ea9001a7b8b55b.1613737828.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/util/vircgroup.c | 11 ++++++++++ + src/util/vircgrouppriv.h | 25 +++++++++++++++++++++++ + src/util/vircgroupv1.c | 44 +++++++++++++++++++++++++++------------- + src/util/vircgroupv2.c | 44 +++++++++++++++++++++++++++------------- + tests/Makefile.am | 1 + + 5 files changed, 97 insertions(+), 28 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index a45c2e7f2f..10b934291c 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -1027,6 +1027,10 @@ virCgroupNewDetectMachine(const char *name, + } + } + ++ (*group)->unitName = virSystemdGetMachineUnitByPID(pid); ++ if (virSystemdHasMachined() == 0 && !(*group)->unitName) ++ return -1; ++ + return 0; + } + +@@ -1146,6 +1150,12 @@ virCgroupNewMachineSystemd(const char *name, + return -1; + } + ++ (*group)->unitName = virSystemdGetMachineUnitByPID(pidleader); ++ if (!(*group)->unitName) { ++ virCgroupFree(group); ++ return -1; ++ } ++ + if (virCgroupAddProcess(*group, pidleader) < 0) { + virErrorPtr saved; + +@@ -3553,6 +3563,7 @@ virCgroupFree(virCgroupPtr *group) + + VIR_FREE((*group)->unified.mountPoint); + VIR_FREE((*group)->unified.placement); ++ VIR_FREE((*group)->unitName); + + VIR_FREE((*group)->path); + VIR_FREE(*group); +diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h +index f2a80aeb82..b4a9e0b379 100644 +--- a/src/util/vircgrouppriv.h ++++ b/src/util/vircgrouppriv.h +@@ -27,6 +27,7 @@ + + #include "vircgroup.h" + #include "vircgroupbackend.h" ++#include "virdbus.h" + + struct _virCgroupV1Controller { + int type; +@@ -66,8 +67,32 @@ struct _virCgroup { + + virCgroupV1Controller legacy[VIR_CGROUP_CONTROLLER_LAST]; + virCgroupV2Controller unified; ++ ++ char *unitName; + }; + ++#define virCgroupSetValueDBus(unitName, key, ...) \ ++ ({ \ ++ int __ret = -1; \ ++ do { \ ++ DBusConnection *__conn; \ ++ if (!(__conn = virDBusGetSystemBus())) \ ++ break; \ ++ __ret = virDBusCallMethod(__conn, NULL, NULL, \ ++ "org.freedesktop.systemd1", \ ++ "/org/freedesktop/systemd1", \ ++ "org.freedesktop.systemd1.Manager", \ ++ "SetUnitProperties", \ ++ "sba(sv)", \ ++ unitName, \ ++ true, \ ++ 1, \ ++ key, \ ++ __VA_ARGS__); \ ++ } while (0); \ ++ __ret; \ ++ }) ++ + int virCgroupSetValueRaw(const char *path, + const char *value); + +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index c35088a3c4..7ec8f3a316 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -931,7 +931,6 @@ virCgroupV1SetBlkioWeight(virCgroupPtr group, + unsigned int weight) + { + g_autofree char *path = NULL; +- g_autofree char *value = NULL; + + if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.bfq.weight", &path) < 0) { +@@ -953,9 +952,14 @@ virCgroupV1SetBlkioWeight(virCgroupPtr group, + return -1; + } + +- value = g_strdup_printf("%u", weight); ++ if (group->unitName) { ++ return virCgroupSetValueDBus(group->unitName, "BlockIOWeight", ++ "t", (unsigned long long) weight); ++ } else { ++ g_autofree char *value = g_strdup_printf("%u", weight); + +- return virCgroupSetValueRaw(path, value); ++ return virCgroupSetValueRaw(path, value); ++ } + } + + +@@ -1188,15 +1192,8 @@ virCgroupV1SetBlkioDeviceWeight(virCgroupPtr group, + const char *devPath, + unsigned int weight) + { +- g_autofree char *str = NULL; +- g_autofree char *blkstr = NULL; + g_autofree char *path = NULL; + +- if (!(blkstr = virCgroupGetBlockDevString(devPath))) +- return -1; +- +- str = g_strdup_printf("%s%d", blkstr, weight); +- + if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.weight_device", &path) < 0) { + return -1; +@@ -1208,7 +1205,21 @@ virCgroupV1SetBlkioDeviceWeight(virCgroupPtr group, + return -1; + } + +- return virCgroupSetValueRaw(path, str); ++ if (group->unitName) { ++ return virCgroupSetValueDBus(group->unitName, "BlockIODeviceWeight", ++ "a(st)", ++ 1, path, (unsigned long long) weight); ++ } else { ++ g_autofree char *str = NULL; ++ g_autofree char *blkstr = NULL; ++ ++ if (!(blkstr = virCgroupGetBlockDevString(devPath))) ++ return -1; ++ ++ str = g_strdup_printf("%s%d", blkstr, weight); ++ ++ return virCgroupSetValueRaw(path, str); ++ } + } + + +@@ -1849,9 +1860,14 @@ static int + virCgroupV1SetCpuShares(virCgroupPtr group, + unsigned long long shares) + { +- return virCgroupSetValueU64(group, +- VIR_CGROUP_CONTROLLER_CPU, +- "cpu.shares", shares); ++ if (group->unitName) { ++ return virCgroupSetValueDBus(group->unitName, "CPUShares", ++ "t", shares); ++ } else { ++ return virCgroupSetValueU64(group, ++ VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.shares", shares); ++ } + } + + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 4682a6a920..8fe4894a9e 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -606,7 +606,6 @@ virCgroupV2SetBlkioWeight(virCgroupPtr group, + unsigned int weight) + { + g_autofree char *path = NULL; +- g_autofree char *value = NULL; + const char *format = "%u"; + + if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, +@@ -630,9 +629,14 @@ virCgroupV2SetBlkioWeight(virCgroupPtr group, + return -1; + } + +- value = g_strdup_printf(format, weight); ++ if (group->unitName) { ++ return virCgroupSetValueDBus(group->unitName, "IOWeight", ++ "t", (unsigned long long) weight); ++ } else { ++ g_autofree char *value = g_strdup_printf(format, weight); + +- return virCgroupSetValueRaw(path, value); ++ return virCgroupSetValueRaw(path, value); ++ } + } + + +@@ -817,13 +821,6 @@ virCgroupV2SetBlkioDeviceWeight(virCgroupPtr group, + unsigned int weight) + { + g_autofree char *path = NULL; +- g_autofree char *str = NULL; +- g_autofree char *blkstr = NULL; +- +- if (!(blkstr = virCgroupGetBlockDevString(devPath))) +- return -1; +- +- str = g_strdup_printf("%s%d", blkstr, weight); + + if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO, + "io.weight", &path) < 0) { +@@ -836,7 +833,21 @@ virCgroupV2SetBlkioDeviceWeight(virCgroupPtr group, + return -1; + } + +- return virCgroupSetValueRaw(path, str); ++ if (group->unitName) { ++ return virCgroupSetValueDBus(group->unitName, "IODeviceWeight", ++ "a(st)", ++ 1, path, (unsigned long long) weight); ++ } else { ++ g_autofree char *str = NULL; ++ g_autofree char *blkstr = NULL; ++ ++ if (!(blkstr = virCgroupGetBlockDevString(devPath))) ++ return -1; ++ ++ str = g_strdup_printf("%s%d", blkstr, weight); ++ ++ return virCgroupSetValueRaw(path, str); ++ } + } + + +@@ -1455,9 +1466,14 @@ static int + virCgroupV2SetCpuShares(virCgroupPtr group, + unsigned long long shares) + { +- return virCgroupSetValueU64(group, +- VIR_CGROUP_CONTROLLER_CPU, +- "cpu.weight", shares); ++ if (group->unitName) { ++ return virCgroupSetValueDBus(group->unitName, "CPUWeight", ++ "t", shares); ++ } else { ++ return virCgroupSetValueU64(group, ++ VIR_CGROUP_CONTROLLER_CPU, ++ "cpu.weight", shares); ++ } + } + + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index f957c7d1ba..b030d0e8f6 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -1188,6 +1188,7 @@ libvirportallocatormock_la_LIBADD = $(MOCKLIBS_LIBS) + + vircgrouptest_SOURCES = \ + vircgrouptest.c testutils.h testutils.c ++vircgrouptest_CFLAGS = $(DBUS_CFLAGS) $(AM_CFLAGS) + vircgrouptest_LDADD = $(LDADDS) + + libvircgroupmock_la_SOURCES = \ +-- +2.30.0 + diff --git a/SOURCES/libvirt-vircgroupv1-refactor-virCgroupV1DetectPlacement.patch b/SOURCES/libvirt-vircgroupv1-refactor-virCgroupV1DetectPlacement.patch new file mode 100644 index 0000000..d8035c1 --- /dev/null +++ b/SOURCES/libvirt-vircgroupv1-refactor-virCgroupV1DetectPlacement.patch @@ -0,0 +1,77 @@ +From a88996cc6c72a6f7fd034c0890747c54cc377484 Mon Sep 17 00:00:00 2001 +Message-Id: <a88996cc6c72a6f7fd034c0890747c54cc377484@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Fri, 19 Feb 2021 13:33:56 +0100 +Subject: [PATCH] vircgroupv1: refactor virCgroupV1DetectPlacement +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Remove one level of indentation by splitting the condition. + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit 5f56dd7c83493f14a471bb9e33415b04329a08bf) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <ce477880853d3a9988389789611b68c458834600.1613737828.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/util/vircgroupv1.c | 39 ++++++++++++++++++++++----------------- + 1 file changed, 22 insertions(+), 17 deletions(-) + +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 7ec8f3a316..09165ece4d 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -339,23 +339,28 @@ virCgroupV1DetectPlacement(virCgroupPtr group, + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + const char *typestr = virCgroupV1ControllerTypeToString(i); + +- if (virCgroupV1MountOptsMatchController(controllers, typestr) && +- group->legacy[i].mountPoint != NULL && +- group->legacy[i].placement == NULL) { +- /* +- * selfpath == "/" + path="" -> "/" +- * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service" +- * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo" +- */ +- if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) { +- group->legacy[i].placement = g_strdup(selfpath); +- } else { +- bool delim = STREQ(selfpath, "/") || STREQ(path, ""); +- +- group->legacy[i].placement = g_strdup_printf("%s%s%s", selfpath, +- delim ? "" : "/", +- path); +- } ++ if (!virCgroupV1MountOptsMatchController(controllers, typestr)) ++ continue; ++ ++ if (!group->legacy[i].mountPoint) ++ continue; ++ ++ if (group->legacy[i].placement) ++ continue; ++ ++ /* ++ * selfpath == "/" + path="" -> "/" ++ * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service" ++ * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo" ++ */ ++ if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) { ++ group->legacy[i].placement = g_strdup(selfpath); ++ } else { ++ bool delim = STREQ(selfpath, "/") || STREQ(path, ""); ++ ++ group->legacy[i].placement = g_strdup_printf("%s%s%s", selfpath, ++ delim ? "" : "/", ++ path); + } + } + +-- +2.30.0 + diff --git a/SOURCES/libvirt-vircgroupv1-use-defines-for-cpu-period-and-quota-limits.patch b/SOURCES/libvirt-vircgroupv1-use-defines-for-cpu-period-and-quota-limits.patch new file mode 100644 index 0000000..649bb1e --- /dev/null +++ b/SOURCES/libvirt-vircgroupv1-use-defines-for-cpu-period-and-quota-limits.patch @@ -0,0 +1,66 @@ +From 2fb78d18ea95c2dcb4c5b0e29171636e51bb2149 Mon Sep 17 00:00:00 2001 +Message-Id: <2fb78d18ea95c2dcb4c5b0e29171636e51bb2149@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Thu, 21 Jan 2021 10:24:04 -0300 +Subject: [PATCH] vircgroupv1: use defines for cpu period and quota limits + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit bc760f4d7c4f964fadcb2a73e126b0053e7a9b06) + +https://bugzilla.redhat.com/1915733 + +Signed-off-by: Daniel Henrique Barboza <dbarboza@redhat.com> +Message-Id: <20210121132406.337681-3-dbarboza@redhat.com> +Reviewed-by: Pavel Hrdina <phrdina@redhat.com> +--- + src/util/vircgroupv1.c | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index d2ec7106db..c35088a3c4 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -1869,13 +1869,13 @@ static int + virCgroupV1SetCpuCfsPeriod(virCgroupPtr group, + unsigned long long cfs_period) + { +- /* The cfs_period should be greater or equal than 1ms, and less or equal +- * than 1s. +- */ +- if (cfs_period < 1000 || cfs_period > 1000000) { ++ if (cfs_period < VIR_CGROUP_CPU_PERIOD_MIN || ++ cfs_period > VIR_CGROUP_CPU_PERIOD_MAX) { + virReportError(VIR_ERR_INVALID_ARG, +- _("cfs_period '%llu' must be in range (1000, 1000000)"), +- cfs_period); ++ _("cfs_period '%llu' must be in range (%llu, %llu)"), ++ cfs_period, ++ VIR_CGROUP_CPU_PERIOD_MIN, ++ VIR_CGROUP_CPU_PERIOD_MAX); + return -1; + } + +@@ -1899,13 +1899,14 @@ static int + virCgroupV1SetCpuCfsQuota(virCgroupPtr group, + long long cfs_quota) + { +- /* The cfs_quota should be greater or equal than 1ms */ + if (cfs_quota >= 0 && +- (cfs_quota < 1000 || +- cfs_quota > ULLONG_MAX / 1000)) { ++ (cfs_quota < VIR_CGROUP_CPU_QUOTA_MIN || ++ cfs_quota > VIR_CGROUP_CPU_QUOTA_MAX)) { + virReportError(VIR_ERR_INVALID_ARG, +- _("cfs_quota '%lld' must be in range (1000, %llu)"), +- cfs_quota, ULLONG_MAX / 1000); ++ _("cfs_quota '%lld' must be in range (%llu, %llu)"), ++ cfs_quota, ++ VIR_CGROUP_CPU_QUOTA_MIN, ++ VIR_CGROUP_CPU_QUOTA_MAX); + return -1; + } + +-- +2.30.0 + diff --git a/SOURCES/libvirt-vircgroupv2-move-task-into-cgroup-before-enabling-controllers.patch b/SOURCES/libvirt-vircgroupv2-move-task-into-cgroup-before-enabling-controllers.patch new file mode 100644 index 0000000..7a161d9 --- /dev/null +++ b/SOURCES/libvirt-vircgroupv2-move-task-into-cgroup-before-enabling-controllers.patch @@ -0,0 +1,155 @@ +From 41a7547b32786b1a84c8ee7bad0c4cf9559ea4b9 Mon Sep 17 00:00:00 2001 +Message-Id: <41a7547b32786b1a84c8ee7bad0c4cf9559ea4b9@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Fri, 19 Feb 2021 13:33:57 +0100 +Subject: [PATCH] vircgroupv2: move task into cgroup before enabling + controllers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When we create a new child cgroup and the parent cgroup has any process +attached to it enabling controllers for the child cgroup fails with +error. We need to move the process into the child cgroup first before +enabling any controllers. + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit 382fa15cde538cba3888a89b301fd3d9a0ce69ea) + +Conflicts: + src/util/vircgroup.c + - missing upstream g_autofree rewrite + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <85d34403caacb571cb78539d5c4f56eee9484d57.1613737828.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/util/vircgroup.c | 13 +++++++------ + src/util/vircgroupbackend.h | 1 + + src/util/vircgroupv1.c | 1 + + src/util/vircgroupv2.c | 13 +++++++++++++ + 4 files changed, 22 insertions(+), 6 deletions(-) + +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index 10b934291c..8f5bcd94f4 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -622,13 +622,14 @@ static int + virCgroupMakeGroup(virCgroupPtr parent, + virCgroupPtr group, + bool create, ++ pid_t pid, + unsigned int flags) + { + size_t i; + + for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) { + if (group->backends[i] && +- group->backends[i]->makeGroup(parent, group, create, flags) < 0) { ++ group->backends[i]->makeGroup(parent, group, create, pid, flags) < 0) { + virCgroupRemove(group); + return -1; + } +@@ -857,8 +858,8 @@ virCgroupNewPartition(const char *path, + goto cleanup; + + if (parent) { +- if (virCgroupMakeGroup(parent, *group, create, VIR_CGROUP_NONE) < 0) +- goto cleanup; ++ if (virCgroupMakeGroup(parent, *group, create, -1, VIR_CGROUP_NONE) < 0) ++ return -1; + } + + ret = 0; +@@ -924,7 +925,7 @@ virCgroupNewDomainPartition(virCgroupPtr partition, + * a group for driver, is to avoid overhead to track + * cumulative usage that we don't need. + */ +- if (virCgroupMakeGroup(partition, *group, create, ++ if (virCgroupMakeGroup(partition, *group, create, -1, + VIR_CGROUP_MEM_HIERACHY) < 0) { + virCgroupFree(group); + return -1; +@@ -978,7 +979,7 @@ virCgroupNewThread(virCgroupPtr domain, + if (virCgroupNew(-1, name, domain, controllers, group) < 0) + return -1; + +- if (virCgroupMakeGroup(domain, *group, create, VIR_CGROUP_THREAD) < 0) { ++ if (virCgroupMakeGroup(domain, *group, create, -1, VIR_CGROUP_THREAD) < 0) { + virCgroupFree(group); + return -1; + } +@@ -1065,7 +1066,7 @@ virCgroupEnableMissingControllers(char *path, + &tmp) < 0) + goto cleanup; + +- if (virCgroupMakeGroup(parent, tmp, true, VIR_CGROUP_SYSTEMD) < 0) { ++ if (virCgroupMakeGroup(parent, tmp, true, -1, VIR_CGROUP_SYSTEMD) < 0) { + virCgroupFree(&tmp); + goto cleanup; + } +diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h +index e12a2e8b9d..ac7b3ae517 100644 +--- a/src/util/vircgroupbackend.h ++++ b/src/util/vircgroupbackend.h +@@ -119,6 +119,7 @@ typedef int + (*virCgroupMakeGroupCB)(virCgroupPtr parent, + virCgroupPtr group, + bool create, ++ pid_t pid, + unsigned int flags); + + typedef int +diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c +index 09165ece4d..eb2b611cee 100644 +--- a/src/util/vircgroupv1.c ++++ b/src/util/vircgroupv1.c +@@ -601,6 +601,7 @@ static int + virCgroupV1MakeGroup(virCgroupPtr parent, + virCgroupPtr group, + bool create, ++ pid_t pid G_GNUC_UNUSED, + unsigned int flags) + { + size_t i; +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 8fe4894a9e..5e19ed8332 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -398,10 +398,17 @@ virCgroupV2EnableController(virCgroupPtr group, + } + + ++static int ++virCgroupV2AddTask(virCgroupPtr group, ++ pid_t pid, ++ unsigned int flags); ++ ++ + static int + virCgroupV2MakeGroup(virCgroupPtr parent, + virCgroupPtr group, + bool create, ++ pid_t pid, + unsigned int flags) + { + g_autofree char *path = NULL; +@@ -449,6 +456,12 @@ virCgroupV2MakeGroup(virCgroupPtr parent, + } + } else { + size_t i; ++ ++ if (pid > 0) { ++ if (virCgroupV2AddTask(group, pid, VIR_CGROUP_TASK_PROCESS) < 0) ++ return -1; ++ } ++ + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + int rc; + +-- +2.30.0 + diff --git a/SOURCES/libvirt-vircgroupv2-properly-detect-placement-of-running-VM.patch b/SOURCES/libvirt-vircgroupv2-properly-detect-placement-of-running-VM.patch new file mode 100644 index 0000000..799b56b --- /dev/null +++ b/SOURCES/libvirt-vircgroupv2-properly-detect-placement-of-running-VM.patch @@ -0,0 +1,88 @@ +From 9cf56b5a0d1394fef10afdd763dc8005457bbaf5 Mon Sep 17 00:00:00 2001 +Message-Id: <9cf56b5a0d1394fef10afdd763dc8005457bbaf5@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Fri, 19 Feb 2021 13:33:51 +0100 +Subject: [PATCH] vircgroupv2: properly detect placement of running VM +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When libvirtd starts a VM it internally stores a path to the main +cgroup. When we restart libvirtd we should get to the same state. + +When we start a VM on host with systemd the cgroup is created for us and +the process is already placed into that cgroup and we detect the path +created by systemd using /proc/$PID/cgroup. After that we create +sub-cgroups and move all threads there. + +Once libvirtd is restarted we again detect the cgroup path using +/proc/$PID/cgroup, but in this case we will get a different path because +the main thread was moved to a "emulator" cgroup. + +Instead of ignoring the "emulator" directory when validating cgroups +remove it completely when detecting cgroup otherwise cgroups will not +work properly when libvirtd is restarted. + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit 902c6644a8ec292789d561b3188e576c37a86872) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <10fb6b61cbb4f9caf8e8ba7706ec01d1da41fc67.1613737828.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/util/vircgroupv2.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 92ae3ec839..4682a6a920 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -121,12 +121,6 @@ virCgroupV2ValidateMachineGroup(virCgroupPtr group, + if (!(tmp = strrchr(group->unified.placement, '/'))) + return false; + +- if (STREQ(tmp, "/emulator")) { +- *tmp = '\0'; +- +- if (!(tmp = strrchr(group->unified.placement, '/'))) +- return false; +- } + tmp++; + + if (STRNEQ(tmp, partmachinename) && +@@ -197,6 +191,9 @@ virCgroupV2DetectPlacement(virCgroupPtr group, + const char *controllers, + const char *selfpath) + { ++ g_autofree char *placement = g_strdup(selfpath); ++ char *tmp = NULL; ++ + if (group->unified.placement) + return 0; + +@@ -207,12 +204,18 @@ virCgroupV2DetectPlacement(virCgroupPtr group, + if (STRNEQ(controllers, "")) + return 0; + ++ /* Running VM will have the main thread placed in emulator cgroup ++ * but we need to get the main cgroup. */ ++ tmp = g_strrstr(placement, "/emulator"); ++ if (tmp) ++ *tmp = '\0'; ++ + /* + * selfpath == "/" + path="" -> "/" + * selfpath == "/libvirt.service" + path == "" -> "/libvirt.service" + * selfpath == "/libvirt.service" + path == "foo" -> "/libvirt.service/foo" + */ +- group->unified.placement = g_strdup_printf("%s%s%s", selfpath, ++ group->unified.placement = g_strdup_printf("%s%s%s", placement, + (STREQ(selfpath, "/") || STREQ(path, "") ? "" : "/"), path); + + return 0; +-- +2.30.0 + diff --git a/SOURCES/libvirt-vircgroupv2-use-defines-for-cpu-period-and-quota-limits.patch b/SOURCES/libvirt-vircgroupv2-use-defines-for-cpu-period-and-quota-limits.patch new file mode 100644 index 0000000..bcb1769 --- /dev/null +++ b/SOURCES/libvirt-vircgroupv2-use-defines-for-cpu-period-and-quota-limits.patch @@ -0,0 +1,78 @@ +From b96501e90f7b3fbea1427ab6adeade7d8e707d07 Mon Sep 17 00:00:00 2001 +Message-Id: <b96501e90f7b3fbea1427ab6adeade7d8e707d07@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Thu, 21 Jan 2021 10:24:05 -0300 +Subject: [PATCH] vircgroupv2: use defines for cpu period and quota limits + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> +(cherry picked from commit 98a09ca48ed4fc011abf2aa290e02ce1b8f1bb5f) + +https://bugzilla.redhat.com/1915733 + +Signed-off-by: Daniel Henrique Barboza <dbarboza@redhat.com> +Message-Id: <20210121132406.337681-4-dbarboza@redhat.com> +Reviewed-by: Pavel Hrdina <phrdina@redhat.com> +--- + src/util/vircgroupv2.c | 25 +++++++++++++------------ + 1 file changed, 13 insertions(+), 12 deletions(-) + +diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c +index 1d8c599f6a..92ae3ec839 100644 +--- a/src/util/vircgroupv2.c ++++ b/src/util/vircgroupv2.c +@@ -1476,12 +1476,12 @@ virCgroupV2SetCpuCfsPeriod(virCgroupPtr group, + g_autofree char *str = NULL; + char *tmp; + +- /* The cfs_period should be greater or equal than 1ms, and less or equal +- * than 1s. +- */ +- if (cfs_period < 1000 || cfs_period > 1000000) { ++ if (cfs_period < VIR_CGROUP_CPU_PERIOD_MIN || ++ cfs_period > VIR_CGROUP_CPU_PERIOD_MAX) { + virReportError(VIR_ERR_INVALID_ARG, +- _("cfs_period '%llu' must be in range (1000, 1000000)"), ++ _("cfs_period '%llu' must be in range (%llu, %llu)"), ++ VIR_CGROUP_CPU_PERIOD_MIN, ++ VIR_CGROUP_CPU_PERIOD_MAX, + cfs_period); + return -1; + } +@@ -1537,17 +1537,18 @@ static int + virCgroupV2SetCpuCfsQuota(virCgroupPtr group, + long long cfs_quota) + { +- /* The cfs_quota should be greater or equal than 1ms */ + if (cfs_quota >= 0 && +- (cfs_quota < 1000 || +- cfs_quota > ULLONG_MAX / 1000)) { ++ (cfs_quota < VIR_CGROUP_CPU_QUOTA_MIN || ++ cfs_quota > VIR_CGROUP_CPU_QUOTA_MAX)) { + virReportError(VIR_ERR_INVALID_ARG, +- _("cfs_quota '%lld' must be in range (1000, %llu)"), +- cfs_quota, ULLONG_MAX / 1000); ++ _("cfs_quota '%lld' must be in range (%llu, %llu)"), ++ cfs_quota, ++ VIR_CGROUP_CPU_QUOTA_MIN, ++ VIR_CGROUP_CPU_QUOTA_MAX); + return -1; + } + +- if (cfs_quota == ULLONG_MAX / 1000) { ++ if (cfs_quota == VIR_CGROUP_CPU_QUOTA_MAX) { + return virCgroupSetValueStr(group, + VIR_CGROUP_CONTROLLER_CPU, + "cpu.max", "max"); +@@ -1572,7 +1573,7 @@ virCgroupV2GetCpuCfsQuota(virCgroupPtr group, + } + + if (STREQLEN(str, "max", 3)) { +- *cfs_quota = ULLONG_MAX / 1000; ++ *cfs_quota = VIR_CGROUP_CPU_QUOTA_MAX; + return 0; + } + +-- +2.30.0 + diff --git a/SOURCES/libvirt-virhostcpu.c-fix-die_id-parsing-for-Power-hosts.patch b/SOURCES/libvirt-virhostcpu.c-fix-die_id-parsing-for-Power-hosts.patch new file mode 100644 index 0000000..2257052 --- /dev/null +++ b/SOURCES/libvirt-virhostcpu.c-fix-die_id-parsing-for-Power-hosts.patch @@ -0,0 +1,94 @@ +From b5aa3a33bc770714f8a68954c05ea362fcfd4d47 Mon Sep 17 00:00:00 2001 +Message-Id: <b5aa3a33bc770714f8a68954c05ea362fcfd4d47@dist-git> +From: Daniel Henrique Barboza <danielhb413@gmail.com> +Date: Mon, 5 Oct 2020 10:25:30 -0400 +Subject: [PATCH] virhostcpu.c: fix 'die_id' parsing for Power hosts + +Commit 7b79ee2f78 makes assumptions about die_id parsing in +the sysfs that aren't true for Power hosts. In both Power8 +and Power9, running 5.6 and 4.18 kernel respectively, +'die_id' is set to -1: + +$ cat /sys/devices/system/cpu/cpu0/topology/die_id +-1 + +This breaks virHostCPUGetDie() parsing because it is trying to +retrieve an unsigned integer, causing problems during VM start: + +virFileReadValueUint:4128 : internal error: Invalid unsigned integer +value '-1' in file '/sys/devices/system/cpu/cpu0/topology/die_id' + +This isn't necessarily a PowerPC only behavior. Linux kernel commit +0e344d8c70 added in the former Documentation/cputopology.txt, now +Documentation/admin-guide/cputopology.rst, that: + + To be consistent on all architectures, include/linux/topology.h + provides default definitions for any of the above macros that are + not defined by include/asm-XXX/topology.h: + + 1) topology_physical_package_id: -1 + 2) topology_die_id: -1 + (...) + +This means that it might be expected that an architecture that +does not implement the die_id element will mark it as -1 in +sysfs. + +It is not required to change die_id implementation from uInt to +Int because of that. Instead, let's change the parsing of the +die_id in virHostCPUGetDie() to read an integer value and, in +case it's -1, default it to zero like in case of file not found. +This is enough to solve the issue Power hosts are experiencing. + +Fixes: 7b79ee2f78bbf2af76df2f6466919e19ae05aeeb +Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit 0137bf0dab2738d5443e2f407239856e2aa25bb3) + +https://bugzilla.redhat.com/show_bug.cgi?id=1876742 + +Signed-off-by: Daniel Henrique Barboza <dbarboza@redhat.com> +Message-Id: <20201005142530.3961036-1-dbarboza@redhat.com> +Reviewed-by: Jiri Denemark <jdenemar@redhat.com> +--- + src/util/virhostcpu.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c +index 09c959cd25..218272d7ec 100644 +--- a/src/util/virhostcpu.c ++++ b/src/util/virhostcpu.c +@@ -221,16 +221,23 @@ virHostCPUGetSocket(unsigned int cpu, unsigned int *socket) + int + virHostCPUGetDie(unsigned int cpu, unsigned int *die) + { +- int ret = virFileReadValueUint(die, +- "%s/cpu/cpu%u/topology/die_id", +- SYSFS_SYSTEM_PATH, cpu); ++ int die_id; ++ int ret = virFileReadValueInt(&die_id, ++ "%s/cpu/cpu%u/topology/die_id", ++ SYSFS_SYSTEM_PATH, cpu); + +- /* If the file is not there, it's 0 */ +- if (ret == -2) +- *die = 0; +- else if (ret < 0) ++ if (ret == -1) + return -1; + ++ /* If the file is not there, it's 0. ++ * Another alternative is die_id set to -1, meaning that ++ * the arch does not have die_id support. Set @die to ++ * 0 in this case too. */ ++ if (ret == -2 || die_id < 0) ++ *die = 0; ++ else ++ *die = die_id; ++ + return 0; + } + +-- +2.28.0 + diff --git a/SOURCES/libvirt-virsh-nodedev-ability-to-filter-CSS-capabilities.patch b/SOURCES/libvirt-virsh-nodedev-ability-to-filter-CSS-capabilities.patch new file mode 100644 index 0000000..ec533f6 --- /dev/null +++ b/SOURCES/libvirt-virsh-nodedev-ability-to-filter-CSS-capabilities.patch @@ -0,0 +1,130 @@ +From 09ce043fb64e92147992898ccdfc9a6c31c6051e Mon Sep 17 00:00:00 2001 +Message-Id: <09ce043fb64e92147992898ccdfc9a6c31c6051e@dist-git> +From: Boris Fiuczynski <fiuczy@linux.ibm.com> +Date: Thu, 8 Oct 2020 11:06:58 -0400 +Subject: [PATCH] virsh: nodedev: ability to filter CSS capabilities + +Allow to filter for CSS devices. + +Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com> +Reviewed-by: Erik Skultety <eskultet@redhat.com> +Signed-off-by: Boris Fiuczynski <fiuczy@linux.ibm.com> +(cherry picked from commit ab655afa186a81ddfd247d2c187c160dd05740e5) +https://bugzilla.redhat.com/show_bug.cgi?id=1853289 +https://bugzilla.redhat.com/show_bug.cgi?id=1865932 +Message-Id: <20201008150700.52157-4-bfiuczyn@redhat.com> +Reviewed-by: Erik Skultety <eskultet@redhat.com> +--- + docs/formatnode.html.in | 12 ++++++++++++ + docs/manpages/virsh.rst | 2 +- + include/libvirt/libvirt-nodedev.h | 1 + + src/conf/node_device_conf.h | 3 ++- + src/conf/virnodedeviceobj.c | 3 ++- + src/libvirt-nodedev.c | 1 + + tools/virsh-nodedev.c | 2 ++ + 7 files changed, 21 insertions(+), 3 deletions(-) + +diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in +index c2a8f8fb7a..0e9658fd29 100644 +--- a/docs/formatnode.html.in ++++ b/docs/formatnode.html.in +@@ -341,6 +341,18 @@ + <dd>The device number.</dd> + </dl> + </dd> ++ <dt><code>css</code></dt> ++ <dd>Describes a Channel SubSystem (CSS) device commonly found on ++ the S390 architecture. Sub-elements include: ++ <dl> ++ <dt><code>cssid</code></dt> ++ <dd>The channel subsystem identifier.</dd> ++ <dt><code>ssid</code></dt> ++ <dd>The subchannel-set identifier.</dd> ++ <dt><code>devno</code></dt> ++ <dd>The device number.</dd> ++ </dl> ++ </dd> + </dl> + </dd> + </dl> +diff --git a/docs/manpages/virsh.rst b/docs/manpages/virsh.rst +index c637caa583..0804465d44 100644 +--- a/docs/manpages/virsh.rst ++++ b/docs/manpages/virsh.rst +@@ -4886,7 +4886,7 @@ List all of the devices available on the node that are known by libvirt. + separated by comma, e.g. --cap pci,scsi. Valid capability types include + 'system', 'pci', 'usb_device', 'usb', 'net', 'scsi_host', 'scsi_target', + 'scsi', 'storage', 'fc_host', 'vports', 'scsi_generic', 'drm', 'mdev', +-'mdev_types', 'ccw'. ++'mdev_types', 'ccw', 'css'. + If *--tree* is used, the output is formatted in a tree representing parents of each + node. *cap* and *--tree* are mutually exclusive. + +diff --git a/include/libvirt/libvirt-nodedev.h b/include/libvirt/libvirt-nodedev.h +index a2ad61ac6d..dd2ffd5782 100644 +--- a/include/libvirt/libvirt-nodedev.h ++++ b/include/libvirt/libvirt-nodedev.h +@@ -81,6 +81,7 @@ typedef enum { + VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES = 1 << 13, /* Capable of mediated devices */ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV = 1 << 14, /* Mediated device */ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV = 1 << 15, /* CCW device */ ++ VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV = 1 << 16, /* CSS device */ + } virConnectListAllNodeDeviceFlags; + + int virConnectListAllNodeDevices (virConnectPtr conn, +diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h +index 19ea3fc7c2..6fe51ed04c 100644 +--- a/src/conf/node_device_conf.h ++++ b/src/conf/node_device_conf.h +@@ -364,7 +364,8 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps); + VIR_CONNECT_LIST_NODE_DEVICES_CAP_DRM | \ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES | \ + VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV | \ +- VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV) ++ VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV | \ ++ VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV) + + int + virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHostPtr scsi_host); +diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c +index 8c8ffd6d24..a27a84355a 100644 +--- a/src/conf/virnodedeviceobj.c ++++ b/src/conf/virnodedeviceobj.c +@@ -827,7 +827,8 @@ virNodeDeviceObjMatch(virNodeDeviceObjPtr obj, + MATCH(DRM) || + MATCH(MDEV_TYPES) || + MATCH(MDEV) || +- MATCH(CCW_DEV))) ++ MATCH(CCW_DEV) || ++ MATCH(CSS_DEV))) + return false; + } + +diff --git a/src/libvirt-nodedev.c b/src/libvirt-nodedev.c +index dce46b7181..71d81f6278 100644 +--- a/src/libvirt-nodedev.c ++++ b/src/libvirt-nodedev.c +@@ -101,6 +101,7 @@ virNodeNumOfDevices(virConnectPtr conn, const char *cap, unsigned int flags) + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV + * VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV ++ * VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV + * + * Returns the number of node devices found or -1 and sets @devices to NULL in + * case of error. On success, the array stored into @devices is guaranteed to +diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c +index 26b3acc608..f4e402c35d 100644 +--- a/tools/virsh-nodedev.c ++++ b/tools/virsh-nodedev.c +@@ -462,6 +462,8 @@ cmdNodeListDevices(vshControl *ctl, const vshCmd *cmd G_GNUC_UNUSED) + flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV; + break; + case VIR_NODE_DEV_CAP_CSS_DEV: ++ flags |= VIR_CONNECT_LIST_NODE_DEVICES_CAP_CSS_DEV; ++ break; + case VIR_NODE_DEV_CAP_LAST: + break; + } +-- +2.28.0 + diff --git a/SOURCES/libvirt-virsystemd-export-virSystemdHasMachined.patch b/SOURCES/libvirt-virsystemd-export-virSystemdHasMachined.patch new file mode 100644 index 0000000..df82c03 --- /dev/null +++ b/SOURCES/libvirt-virsystemd-export-virSystemdHasMachined.patch @@ -0,0 +1,65 @@ +From c8fb30409d501e5d9299ac7c08c43917b199a72b Mon Sep 17 00:00:00 2001 +Message-Id: <c8fb30409d501e5d9299ac7c08c43917b199a72b@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Fri, 19 Feb 2021 13:33:52 +0100 +Subject: [PATCH] virsystemd: export virSystemdHasMachined +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit a51147d9065217d9087449b4e601e3294c0a22cf) + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <9a861adc0dc51679d7178e464255c80465247333.1613737828.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/libvirt_private.syms | 1 + + src/util/virsystemd.c | 2 +- + src/util/virsystemd.h | 2 ++ + 3 files changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 9d87e2a27b..a869d1f7a4 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -3243,6 +3243,7 @@ virSystemdGetActivation; + virSystemdGetMachineNameByPID; + virSystemdHasLogind; + virSystemdHasLogindResetCachedValue; ++virSystemdHasMachined; + virSystemdHasMachinedResetCachedValue; + virSystemdMakeScopeName; + virSystemdMakeSliceName; +diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c +index 96d43e5440..ca708cd1bd 100644 +--- a/src/util/virsystemd.c ++++ b/src/util/virsystemd.c +@@ -153,7 +153,7 @@ void virSystemdHasLogindResetCachedValue(void) + * -1 = error + * 0 = machine1 is available + */ +-static int ++int + virSystemdHasMachined(void) + { + int ret; +diff --git a/src/util/virsystemd.h b/src/util/virsystemd.h +index dfea75948b..9ce16b7de1 100644 +--- a/src/util/virsystemd.h ++++ b/src/util/virsystemd.h +@@ -57,6 +57,8 @@ int virSystemdTerminateMachine(const char *name); + + void virSystemdNotifyStartup(void); + ++int virSystemdHasMachined(void); ++ + int virSystemdHasLogind(void); + + int virSystemdCanSuspend(bool *result); +-- +2.30.0 + diff --git a/SOURCES/libvirt-virsystemd-introduce-virSystemdGetMachineByPID.patch b/SOURCES/libvirt-virsystemd-introduce-virSystemdGetMachineByPID.patch new file mode 100644 index 0000000..c7242c1 --- /dev/null +++ b/SOURCES/libvirt-virsystemd-introduce-virSystemdGetMachineByPID.patch @@ -0,0 +1,102 @@ +From a3a5c16f04d044502eecedbef6043bce79043df9 Mon Sep 17 00:00:00 2001 +Message-Id: <a3a5c16f04d044502eecedbef6043bce79043df9@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Fri, 19 Feb 2021 13:33:53 +0100 +Subject: [PATCH] virsystemd: introduce virSystemdGetMachineByPID +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit 385704d5a4e1c02c21fb5779fa5067cf0d8ab56c) + +Conflicts: + src/util/virsystemd.c + - missing upstream glib dbus rewrite + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <7de7eae45f139e79c45731263924ae078f3e33c5.1613737828.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/util/virsystemd.c | 46 +++++++++++++++++++++++++++++++++---------- + 1 file changed, 36 insertions(+), 10 deletions(-) + +diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c +index ca708cd1bd..394eb13f38 100644 +--- a/src/util/virsystemd.c ++++ b/src/util/virsystemd.c +@@ -200,19 +200,24 @@ virSystemdHasLogind(void) + } + + +-char * +-virSystemdGetMachineNameByPID(pid_t pid) ++/** ++ * virSystemdGetMachineByPID: ++ * @conn: dbus connection ++ * @pid: pid of running VM ++ * ++ * Returns dbus object path to VM registered with machined. ++ * On error returns NULL. ++ */ ++static char * ++virSystemdGetMachineByPID(DBusConnection *conn, ++ pid_t pid) + { +- DBusConnection *conn; + DBusMessage *reply = NULL; +- char *name = NULL, *object = NULL; ++ char *object = NULL; + + if (virSystemdHasMachined() < 0) + goto cleanup; + +- if (!(conn = virDBusGetSystemBus())) +- goto cleanup; +- + if (virDBusCallMethod(conn, &reply, NULL, + "org.freedesktop.machine1", + "/org/freedesktop/machine1", +@@ -224,12 +229,33 @@ virSystemdGetMachineNameByPID(pid_t pid) + if (virDBusMessageDecode(reply, "o", &object) < 0) + goto cleanup; + +- virDBusMessageUnref(reply); +- reply = NULL; +- + VIR_DEBUG("Domain with pid %lld has object path '%s'", + (long long) pid, object); + ++ cleanup: ++ virDBusMessageUnref(reply); ++ ++ return object; ++} ++ ++ ++char * ++virSystemdGetMachineNameByPID(pid_t pid) ++{ ++ DBusConnection *conn; ++ DBusMessage *reply = NULL; ++ char *name = NULL, *object = NULL; ++ ++ if (virSystemdHasMachined() < 0) ++ goto cleanup; ++ ++ if (!(conn = virDBusGetSystemBus())) ++ goto cleanup; ++ ++ object = virSystemdGetMachineByPID(conn, pid); ++ if (!object) ++ goto cleanup; ++ + if (virDBusCallMethod(conn, &reply, NULL, + "org.freedesktop.machine1", + object, +-- +2.30.0 + diff --git a/SOURCES/libvirt-virsystemd-introduce-virSystemdGetMachineUnitByPID.patch b/SOURCES/libvirt-virsystemd-introduce-virSystemdGetMachineUnitByPID.patch new file mode 100644 index 0000000..5918571 --- /dev/null +++ b/SOURCES/libvirt-virsystemd-introduce-virSystemdGetMachineUnitByPID.patch @@ -0,0 +1,205 @@ +From 9ec1193393c48198fd05b795bcce0d607b45d4ee Mon Sep 17 00:00:00 2001 +Message-Id: <9ec1193393c48198fd05b795bcce0d607b45d4ee@dist-git> +From: Pavel Hrdina <phrdina@redhat.com> +Date: Fri, 19 Feb 2021 13:33:54 +0100 +Subject: [PATCH] virsystemd: introduce virSystemdGetMachineUnitByPID +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Reviewed-by: Michal Privoznik <mprivozn@redhat.com> +(cherry picked from commit d3fb774b1ed548c0338b3338a87094dafea32aa2) + +Conflicts: + src/util/virsystemd.c + tests/virsystemdtest.c + - missing upstream glib dbus rewrite + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463 + +Signed-off-by: Pavel Hrdina <phrdina@redhat.com> +Message-Id: <28be8d962cde455d215fe9ee09fbdcc4145e931f.1613737828.git.phrdina@redhat.com> +Reviewed-by: Ján Tomko <jtomko@redhat.com> +--- + src/libvirt_private.syms | 1 + + src/util/virsystemd.c | 48 ++++++++++++++++++++++++++++++++ + src/util/virsystemd.h | 2 ++ + tests/virsystemdtest.c | 59 ++++++++++++++++++++++++++++++++++------ + 4 files changed, 101 insertions(+), 9 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index a869d1f7a4..af6f32fb1e 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -3241,6 +3241,7 @@ virSystemdCanSuspend; + virSystemdCreateMachine; + virSystemdGetActivation; + virSystemdGetMachineNameByPID; ++virSystemdGetMachineUnitByPID; + virSystemdHasLogind; + virSystemdHasLogindResetCachedValue; + virSystemdHasMachined; +diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c +index 394eb13f38..0b8e21ae46 100644 +--- a/src/util/virsystemd.c ++++ b/src/util/virsystemd.c +@@ -280,6 +280,54 @@ virSystemdGetMachineNameByPID(pid_t pid) + } + + ++/** ++ * virSystemdGetMachineUnitByPID: ++ * @pid: pid of running VM ++ * ++ * Returns systemd Unit name of a running VM registered with machined. ++ * On error returns NULL. ++ */ ++char * ++virSystemdGetMachineUnitByPID(pid_t pid) ++{ ++ DBusConnection *conn; ++ DBusMessage *reply = NULL; ++ char *unit = NULL, *object = NULL; ++ ++ if (virSystemdHasMachined() < 0) ++ goto cleanup; ++ ++ if (!(conn = virDBusGetSystemBus())) ++ goto cleanup; ++ ++ object = virSystemdGetMachineByPID(conn, pid); ++ if (!object) ++ goto cleanup; ++ ++ if (virDBusCallMethod(conn, &reply, NULL, ++ "org.freedesktop.machine1", ++ object, ++ "org.freedesktop.DBus.Properties", ++ "Get", ++ "ss", ++ "org.freedesktop.machine1.Machine", ++ "Unit") < 0) ++ goto cleanup; ++ ++ if (virDBusMessageDecode(reply, "v", "s", &unit) < 0) ++ goto cleanup; ++ ++ VIR_DEBUG("Domain with pid %lld has unit name '%s'", ++ (long long) pid, unit); ++ ++ cleanup: ++ VIR_FREE(object); ++ virDBusMessageUnref(reply); ++ ++ return unit; ++} ++ ++ + /** + * virSystemdCreateMachine: + * @name: driver unique name of the machine +diff --git a/src/util/virsystemd.h b/src/util/virsystemd.h +index 9ce16b7de1..cd329c49f9 100644 +--- a/src/util/virsystemd.h ++++ b/src/util/virsystemd.h +@@ -69,6 +69,8 @@ int virSystemdCanHybridSleep(bool *result); + + char *virSystemdGetMachineNameByPID(pid_t pid); + ++char *virSystemdGetMachineUnitByPID(pid_t pid); ++ + int virSystemdGetActivation(virSystemdActivationMap *map, + size_t nmap, + virSystemdActivationPtr *act); +diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c +index eb510b40e4..475bf8debc 100644 +--- a/tests/virsystemdtest.c ++++ b/tests/virsystemdtest.c +@@ -69,19 +69,42 @@ VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block, + &object_path)) + goto error; + } else if (STREQ(member, "Get")) { +- const char *name = "qemu-demo"; ++ const char *name = NULL; ++ char *iface = NULL; ++ char *prop = NULL; + DBusMessageIter iter; + DBusMessageIter sub; + +- dbus_message_iter_init_append(reply, &iter); +- dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, +- "s", &sub); +- +- if (!dbus_message_iter_append_basic(&sub, +- DBUS_TYPE_STRING, +- &name)) ++ if (virDBusMessageDecode(message, "ss", &iface, &prop) < 0) + goto error; +- dbus_message_iter_close_container(&iter, &sub); ++ ++ VIR_FREE(iface); ++ ++ if (STREQ(prop, "Name")) { ++ name = "qemu-demo"; ++ } else if (STREQ(prop, "Unit")) { ++ name = "machine-qemu-demo.scope"; ++ } else { ++ dbus_set_error_const(error, ++ "org.freedesktop.systemd.badthing", ++ "Unknown machine property"); ++ } ++ ++ VIR_FREE(prop); ++ ++ if (name) { ++ dbus_message_iter_init_append(reply, &iter); ++ ++ dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, ++ "s", &sub); ++ ++ if (!dbus_message_iter_append_basic(&sub, ++ DBUS_TYPE_STRING, ++ &name)) ++ goto error; ++ ++ dbus_message_iter_close_container(&iter, &sub); ++ } + } + } + } else if (STREQ(service, "org.freedesktop.login1")) { +@@ -376,6 +399,23 @@ testGetMachineName(const void *opaque G_GNUC_UNUSED) + } + + ++static int ++testGetMachineUnit(const void *opaque G_GNUC_UNUSED) ++{ ++ g_autofree char *tmp = virSystemdGetMachineUnitByPID(1234); ++ ++ if (!tmp) { ++ fprintf(stderr, "%s", "Failed to create get machine unit\n"); ++ return -1; ++ } ++ ++ if (STREQ(tmp, "machine-qemu-demo.scope")) ++ return 0; ++ ++ return -1; ++} ++ ++ + struct testNameData { + const char *name; + const char *expected; +@@ -698,6 +738,7 @@ mymain(void) + DO_TEST("Test create bad systemd ", testCreateBadSystemd); + DO_TEST("Test create with network ", testCreateNetwork); + DO_TEST("Test getting machine name ", testGetMachineName); ++ DO_TEST("Test getting machine unit ", testGetMachineUnit); + + # define TEST_SCOPE(_name, unitname, _legacy) \ + do { \ +-- +2.30.0 + diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec index a5bc743..e3acab3 100644 --- a/SPECS/libvirt.spec +++ b/SPECS/libvirt.spec @@ -219,7 +219,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 6.0.0 -Release: 28.1%{?dist}%{?extra_release} +Release: 35%{?dist}%{?extra_release} License: LGPLv2+ URL: https://libvirt.org/ @@ -669,7 +669,91 @@ Patch437: libvirt-virDevMapperGetTargets-Don-t-ignore-EBADF.patch Patch438: libvirt-virdevmapper-Don-t-cache-device-mapper-major.patch Patch439: libvirt-virdevmapper-Handle-kernel-without-device-mapper-support.patch Patch440: libvirt-virdevmapper-Ignore-all-errors-when-opening-dev-mapper-control.patch -Patch441: libvirt-qemu-Add-virtio-related-options-to-vsock.patch +Patch441: libvirt-qemu-substitute-missing-model-name-for-host-passthrough.patch +Patch442: libvirt-rpc-gendispatch-handle-empty-flags.patch +Patch443: libvirt-rpc-add-support-for-filtering-acls-by-uint-params.patch +Patch444: libvirt-rpc-require-write-acl-for-guest-agent-in-virDomainInterfaceAddresses.patch +Patch445: libvirt-qemu-agent-set-ifname-to-NULL-after-freeing.patch +Patch446: libvirt-qemu-Fix-domfsinfo-for-non-PCI-device-information-from-guest-agent.patch +Patch447: libvirt-virDomainNetFindIdx-add-support-for-CCW-addresses.patch +Patch448: libvirt-check-for-NULL-before-calling-g_regex_unref.patch +Patch449: libvirt-virhostcpu.c-fix-die_id-parsing-for-Power-hosts.patch +Patch450: libvirt-qemuFirmwareFillDomain-Fill-NVRAM-template-on-migration-too.patch +Patch451: libvirt-node_device-refactor-udevProcessCCW.patch +Patch452: libvirt-node_device-detect-CSS-devices.patch +Patch453: libvirt-virsh-nodedev-ability-to-filter-CSS-capabilities.patch +Patch454: libvirt-node_device-detect-DASD-devices.patch +Patch455: libvirt-udevProcessCSS-Check-if-def-driver-is-non-NULL.patch +Patch456: libvirt-cpu_map-Add-missing-x86-features-in-0x7-CPUID-leaf.patch +Patch457: libvirt-cpu_map-Add-missing-x86-features-in-0x80000008-CPUID-leaf.patch +Patch458: libvirt-cpu_map-Add-missing-AMD-SVM-features.patch +Patch459: libvirt-Add-testdata-for-AMD-EPYC-7502.patch +Patch460: libvirt-cpu_map-Defined-and-enable-EPYC-Rome-model.patch +Patch461: libvirt-cpu_map-Remove-monitor-feature-from-EPYC-Rome.patch +Patch462: libvirt-tests-qemuxml2argv-Use-existing-machine-type-for-numatune-distances-case.patch +Patch463: libvirt-qemuxml2xmltest-Add-numatune-distance-test-case.patch +Patch464: libvirt-conf-Move-and-rename-virDomainParseScaledValue.patch +Patch465: libvirt-numa_conf-Drop-CPU-from-name-of-two-functions.patch +Patch466: libvirt-qemu_command-Rename-qemuBuildNumaArgStr.patch +Patch467: libvirt-qemuBuildMachineCommandLine-Drop-needless-check.patch +Patch468: libvirt-numa_conf-Make-virDomainNumaSetNodeCpumask-return-void.patch +Patch469: libvirt-Allow-NUMA-nodes-without-vCPUs.patch +Patch470: libvirt-conf-Parse-and-format-HMAT.patch +Patch471: libvirt-conf-Validate-NUMA-HMAT-configuration.patch +Patch472: libvirt-numa-expose-HMAT-APIs.patch +Patch473: libvirt-qemu-Introduce-QEMU_CAPS_NUMA_HMAT-capability.patch +Patch474: libvirt-qemu-Build-HMAT-command-line.patch +Patch475: libvirt-qemuBuildNumaCommandLine-Fix-masterInitiator-check.patch +Patch476: libvirt-numa_conf-Properly-check-for-caches-in-virDomainNumaDefValidate.patch +Patch477: libvirt-RNG-Allow-interleaving-of-domain-cpu-numa-cell-children.patch +Patch478: libvirt-conf-properly-clear-out-autogenerated-macvtap-names-when-formatting-parsing.patch +Patch479: libvirt-qemu-format-ramfb-attribute-for-mediated-devices.patch +Patch480: libvirt-util-replace-macvtap-name-reservation-bitmap-with-a-simple-counter.patch +Patch481: libvirt-util-assign-tap-device-names-using-a-monotonically-increasing-integer.patch +Patch482: libvirt-util-virNetDevTapCreate-initialize-fd-to-1.patch +Patch483: libvirt-cpu_map-Fix-Icelake-Server-model-number.patch +Patch484: libvirt-cputestdata-Add-test-data-for-Snowridge.patch +Patch485: libvirt-cpu_map-Add-support-for-fsrm-CPU-feature.patch +Patch486: libvirt-cpu_map-Add-support-for-core-capability-CPU-feature.patch +Patch487: libvirt-cpu_map-Add-support-for-split-lock-detect-CPU-feature.patch +Patch488: libvirt-cpu_map-Define-and-enable-Snowridge-model.patch +Patch489: libvirt-util-fix-typo-in-VIR_MOCK_WRAP_RET_ARGS.patch +Patch490: libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-in-unit-tests.patch +Patch491: libvirt-util-tests-enable-locking-on-iptables-ebtables-commandlines-by-default.patch +Patch492: libvirt-tests-fix-iptables-test-case-commandline-options-in-virfirewalltest.c.patch +Patch493: libvirt-network-be-more-verbose-about-the-reason-for-a-firewall-reload.patch +Patch494: libvirt-util-always-check-for-ebtables-iptables-binaries-even-when-using-firewalld.patch +Patch495: libvirt-util-synchronize-with-firewalld-before-we-start-calling-iptables-directly.patch +Patch496: libvirt-util-call-iptables-directly-rather-than-via-firewalld.patch +Patch497: libvirt-util-virhostcpu-Fail-when-fetching-CPU-Stats-for-invalid-cpu.patch +Patch498: libvirt-qemu-move-cgroup-cpu-period-and-quota-defines-to-vircgroup.h.patch +Patch499: libvirt-vircgroupv1-use-defines-for-cpu-period-and-quota-limits.patch +Patch500: libvirt-vircgroupv2-use-defines-for-cpu-period-and-quota-limits.patch +Patch501: libvirt-vircgroup-fix-cpu-quota-maximum-limit.patch +Patch502: libvirt-util-add-virNetDevGetPhysPortName.patch +Patch503: libvirt-util-avoid-manual-VIR_FREE-of-a-g_autofree-pointer-in-virPCIGetName.patch +Patch504: libvirt-util-Add-phys_port_name-support-on-virPCIGetNetName.patch +Patch505: libvirt-vircgroupv2-properly-detect-placement-of-running-VM.patch +Patch506: libvirt-virsystemd-export-virSystemdHasMachined.patch +Patch507: libvirt-virsystemd-introduce-virSystemdGetMachineByPID.patch +Patch508: libvirt-virsystemd-introduce-virSystemdGetMachineUnitByPID.patch +Patch509: libvirt-vircgroup-use-DBus-call-to-systemd-for-some-APIs.patch +Patch510: libvirt-vircgroupv1-refactor-virCgroupV1DetectPlacement.patch +Patch511: libvirt-vircgroupv2-move-task-into-cgroup-before-enabling-controllers.patch +Patch512: libvirt-vircgroup-introduce-virCgroupV1Exists-and-virCgroupV2Exists.patch +Patch513: libvirt-vircgroup-introduce-nested-cgroup-to-properly-work-with-systemd.patch +Patch514: libvirt-tests-add-cgroup-nested-tests.patch +Patch515: libvirt-vircgroup-correctly-free-nested-virCgroupPtr.patch +Patch516: libvirt-qemu-Add-virtio-related-options-to-vsock.patch +Patch517: libvirt-domain_validate-use-defines-for-cpu-period-and-quota-limits.patch +Patch518: libvirt-docs-use-proper-cpu-quota-value-in-our-documentation.patch +Patch519: libvirt-vircgroup-enforce-range-limit-for-cpu.shares.patch +Patch520: libvirt-cgroup-use-virCgroupSetCpuShares-instead-of-virCgroupSetupCpuShares.patch +Patch521: libvirt-cpumap-Add-support-for-ibrs-CPU-feature.patch +Patch522: libvirt-cpumap-Add-support-for-svme-addr-check-CPU-feature.patch +Patch523: libvirt-cpu_map-Add-EPYC-Milan-x86-CPU-model.patch +Patch524: libvirt-cpu_map-Install-x86_EPYC-Milan.xml.patch +Patch525: libvirt-cpu_map-Fix-spelling-of-svme-addr-chk-feature.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2446,8 +2530,104 @@ exit 0 %changelog -* Tue Mar 23 2021 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-28.1.el8 -- qemu: Add virtio related options to vsock (rhbz#1941820) +* Thu Mar 4 2021 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-35 +- vircgroupv2: properly detect placement of running VM (rhbz#1798463) +- virsystemd: export virSystemdHasMachined (rhbz#1798463) +- virsystemd: introduce virSystemdGetMachineByPID (rhbz#1798463) +- virsystemd: introduce virSystemdGetMachineUnitByPID (rhbz#1798463) +- vircgroup: use DBus call to systemd for some APIs (rhbz#1798463) +- vircgroupv1: refactor virCgroupV1DetectPlacement (rhbz#1798463) +- vircgroupv2: move task into cgroup before enabling controllers (rhbz#1798463) +- vircgroup: introduce virCgroupV1Exists and virCgroupV2Exists (rhbz#1798463) +- vircgroup: introduce nested cgroup to properly work with systemd (rhbz#1798463) +- tests: add cgroup nested tests (rhbz#1798463) +- vircgroup: correctly free nested virCgroupPtr (rhbz#1798463) +- qemu: Add virtio related options to vsock (rhbz#1931548) +- domain_validate: use defines for cpu period and quota limits (rhbz#1798463) +- docs: use proper cpu quota value in our documentation (rhbz#1798463) +- vircgroup: enforce range limit for cpu.shares (rhbz#1798463) +- cgroup: use virCgroupSetCpuShares instead of virCgroupSetupCpuShares (rhbz#1798463) +- cpumap: Add support for ibrs CPU feature (rhbz#1926864) +- cpumap: Add support for svme-addr-check CPU feature (rhbz#1926864) +- cpu_map: Add EPYC-Milan x86 CPU model (rhbz#1926864) +- cpu_map: Install x86_EPYC-Milan.xml (rhbz#1926864) +- cpu_map: Fix spelling of svme-addr-chk feature (rhbz#1926864) + +* Mon Feb 1 2021 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-34 +- qemu: move cgroup cpu period and quota defines to vircgroup.h (rhbz#1915733) +- vircgroupv1: use defines for cpu period and quota limits (rhbz#1915733) +- vircgroupv2: use defines for cpu period and quota limits (rhbz#1915733) +- vircgroup: fix cpu quota maximum limit (rhbz#1915733) +- util: add virNetDevGetPhysPortName (rhbz#1918708) +- util: avoid manual VIR_FREE of a g_autofree pointer in virPCIGetName() (rhbz#1918708) +- util: Add phys_port_name support on virPCIGetNetName (rhbz#1918708) + +* Thu Jan 21 2021 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-33 +- cpu_map: Fix Icelake Server model number (rhbz#1537734) +- cputestdata: Add test data for Snowridge (rhbz#1537734) +- cpu_map: Add support for fsrm CPU feature (rhbz#1537734) +- cpu_map: Add support for core-capability CPU feature (rhbz#1537734) +- cpu_map: Add support for split-lock-detect CPU feature (rhbz#1537734) +- cpu_map: Define and enable Snowridge model (rhbz#1537734) +- util: fix typo in VIR_MOCK_WRAP_RET_ARGS() (rhbz#1607929) +- util/tests: enable locking on iptables/ebtables commandlines in unit tests (rhbz#1607929) +- util/tests: enable locking on iptables/ebtables commandlines by default (rhbz#1607929) +- tests: fix iptables test case commandline options in virfirewalltest.c (rhbz#1607929) +- network: be more verbose about the reason for a firewall reload (rhbz#1607929) +- util: always check for ebtables/iptables binaries, even when using firewalld (rhbz#1607929) +- util: synchronize with firewalld before we start calling iptables directly (rhbz#1607929) +- util: call iptables directly rather than via firewalld (rhbz#1607929) +- util: virhostcpu: Fail when fetching CPU Stats for invalid cpu (rhbz#1915183) + +* Tue Dec 15 2020 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-32 +- util: replace macvtap name reservation bitmap with a simple counter (rhbz#1874304) +- util: assign tap device names using a monotonically increasing integer (rhbz#1874304) +- util: virNetDevTapCreate: initialize fd to -1 (rhbz#1874304) + +* Thu Dec 10 2020 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-31 +- conf: properly clear out autogenerated macvtap names when formatting/parsing (rhbz#1872610) +- qemu: format 'ramfb' attribute for mediated devices (rhbz#1876297) + +* Mon Nov 9 2020 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-30 +- cpu_map: Add missing x86 features in 0x7 CPUID leaf (rhbz#1861506) +- cpu_map: Add missing x86 features in 0x80000008 CPUID leaf (rhbz#1861506) +- cpu_map: Add missing AMD SVM features (rhbz#1861506) +- Add testdata for AMD EPYC 7502 (rhbz#1861506) +- cpu_map: Defined and enable EPYC-Rome model (rhbz#1861506) +- cpu_map: Remove monitor feature from EPYC-Rome (rhbz#1861506) +- tests: qemuxml2argv: Use existing machine type for 'numatune-distances' case (rhbz#1749518) +- qemuxml2xmltest: Add "numatune-distance" test case (rhbz#1749518) +- conf: Move and rename virDomainParseScaledValue() (rhbz#1749518) +- numa_conf: Drop CPU from name of two functions (rhbz#1749518) +- qemu_command: Rename qemuBuildNumaArgStr() (rhbz#1749518) +- qemuBuildMachineCommandLine: Drop needless check (rhbz#1749518) +- numa_conf: Make virDomainNumaSetNodeCpumask() return void (rhbz#1749518) +- Allow NUMA nodes without vCPUs (rhbz#1749518) +- conf: Parse and format HMAT (rhbz#1749518) +- conf: Validate NUMA HMAT configuration (rhbz#1749518) +- numa: expose HMAT APIs (rhbz#1749518) +- qemu: Introduce QEMU_CAPS_NUMA_HMAT capability (rhbz#1749518) +- qemu: Build HMAT command line (rhbz#1749518) +- qemuBuildNumaCommandLine: Fix @masterInitiator check (rhbz#1749518) +- numa_conf: Properly check for caches in virDomainNumaDefValidate() (rhbz#1749518) +- RNG: Allow interleaving of /domain/cpu/numa/cell children (rhbz#1749518) + +* Fri Oct 9 2020 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-29 +- qemu: substitute missing model name for host-passthrough (rhbz#1850680) +- rpc: gendispatch: handle empty flags (CVE-2020-25637) +- rpc: add support for filtering @acls by uint params (CVE-2020-25637) +- rpc: require write acl for guest agent in virDomainInterfaceAddresses (CVE-2020-25637) +- qemu: agent: set ifname to NULL after freeing (CVE-2020-25637) +- qemu: Fix domfsinfo for non-PCI device information from guest agent (rhbz#1858771) +- virDomainNetFindIdx: add support for CCW addresses (rhbz#1837495) +- check for NULL before calling g_regex_unref (rhbz#1861176) +- virhostcpu.c: fix 'die_id' parsing for Power hosts (rhbz#1876742) +- qemuFirmwareFillDomain: Fill NVRAM template on migration too (rhbz#1880418) +- node_device: refactor udevProcessCCW (rhbz#1853289, rhbz#1865932) +- node_device: detect CSS devices (rhbz#1853289, rhbz#1865932) +- virsh: nodedev: ability to filter CSS capabilities (rhbz#1853289, rhbz#1865932) +- node_device: detect DASD devices (rhbz#1853289, rhbz#1865932) +- udevProcessCSS: Check if def->driver is non-NULL (rhbz#1853289, rhbz#1865932) * Wed Aug 26 2020 Jiri Denemark <jdenemar@redhat.com> - 6.0.0-28 - virdevmapper: Don't cache device-mapper major (rhbz#1860421)