diff --git a/kvm-Revert-Re-enable-capstone-internal-build.patch b/kvm-Revert-Re-enable-capstone-internal-build.patch new file mode 100644 index 0000000..3dbb5ca --- /dev/null +++ b/kvm-Revert-Re-enable-capstone-internal-build.patch @@ -0,0 +1,252 @@ +From 4ce18f26f30cfb8860153825c504289f43800f5e Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Mon, 19 Sep 2022 03:23:41 -0400 +Subject: [PATCH 28/29] Revert "Re-enable capstone internal build" + +RH-Author: Miroslav Rezanina +RH-MergeRequest: 119: Use capstone package for qemu-kvm build +RH-Bugzilla: 2127825 +RH-Acked-by: Thomas Huth +RH-Commit: [1/2] bd58ace2233e3071703a69ea9e7bfcd82416cda1 (mrezanin/centos-src-qemu-kvm) + +This reverts commit c2c10b636a97d1cb9c4abbc4152a34ebf2f44817. + +Signed-off-by: Miroslav Rezanina +--- + configure | 12 ---- + meson.build | 116 ++-------------------------------- + meson_options.txt | 3 +- + scripts/meson-buildoptions.sh | 5 +- + 4 files changed, 7 insertions(+), 129 deletions(-) + +diff --git a/configure b/configure +index 448b0c82cb..72ab03f11a 100755 +--- a/configure ++++ b/configure +@@ -322,10 +322,8 @@ vfio_user_server="disabled" + + # 1. Track which submodules are needed + if test "$default_feature" = no ; then +- capstone="disabled" + slirp="disabled" + else +- capstone="auto" + slirp="auto" + fi + fdt="auto" +@@ -904,15 +902,6 @@ for opt do + --enable-uuid|--disable-uuid) + echo "$0: $opt is obsolete, UUID support is always built" >&2 + ;; +- --disable-capstone) capstone="disabled" +- ;; +- --enable-capstone) capstone="enabled" +- ;; +- --enable-capstone=git) capstone="internal" +- ;; +- --enable-capstone=*) capstone="$optarg" +- ;; +- + --with-git=*) git="$optarg" + ;; + --with-git-submodules=*) +@@ -2753,7 +2742,6 @@ if test "$skip_meson" = no; then + test "$werror" = yes && meson_option_add -Dwerror=true + + # QEMU options +- test "$capstone" != auto && meson_option_add "-Dcapstone=$capstone" + test "$cfi" != false && meson_option_add "-Dcfi=$cfi" + test "$fdt" != auto && meson_option_add "-Dfdt=$fdt" + test -n "${LIB_FUZZING_ENGINE+xxx}" && meson_option_add "-Dfuzzing_engine=$LIB_FUZZING_ENGINE" +diff --git a/meson.build b/meson.build +index 9e6a979c13..20fddbd707 100644 +--- a/meson.build ++++ b/meson.build +@@ -2596,13 +2596,10 @@ genh += custom_target('config-poison.h', + ############## + + capstone = not_found +-capstone_opt = get_option('capstone') +-if capstone_opt in ['enabled', 'auto', 'system'] +- have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile') ++if not get_option('capstone').auto() or have_system or have_user + capstone = dependency('capstone', version: '>=3.0.5', + kwargs: static_kwargs, method: 'pkg-config', +- required: capstone_opt == 'system' or +- capstone_opt == 'enabled' and not have_internal) ++ required: get_option('capstone')) + + # Some versions of capstone have broken pkg-config file + # that reports a wrong -I path, causing the #include to +@@ -2611,113 +2608,10 @@ if capstone_opt in ['enabled', 'auto', 'system'] + if capstone.found() and not cc.compiles('#include ', + dependencies: [capstone]) + capstone = not_found +- if capstone_opt == 'system' +- error('system capstone requested, it does not appear to work') ++ if get_option('capstone').enabled() ++ error('capstone requested, but it does not appear to work') + endif + endif +- +- if capstone.found() +- capstone_opt = 'system' +- elif have_internal +- capstone_opt = 'internal' +- else +- capstone_opt = 'disabled' +- endif +-endif +-if capstone_opt == 'internal' +- capstone_data = configuration_data() +- capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1') +- +- capstone_files = files( +- 'capstone/cs.c', +- 'capstone/MCInst.c', +- 'capstone/MCInstrDesc.c', +- 'capstone/MCRegisterInfo.c', +- 'capstone/SStream.c', +- 'capstone/utils.c' +- ) +- +- if 'CONFIG_ARM_DIS' in config_all_disas +- capstone_data.set('CAPSTONE_HAS_ARM', '1') +- capstone_files += files( +- 'capstone/arch/ARM/ARMDisassembler.c', +- 'capstone/arch/ARM/ARMInstPrinter.c', +- 'capstone/arch/ARM/ARMMapping.c', +- 'capstone/arch/ARM/ARMModule.c' +- ) +- endif +- +- # FIXME: This config entry currently depends on a c++ compiler. +- # Which is needed for building libvixl, but not for capstone. +- if 'CONFIG_ARM_A64_DIS' in config_all_disas +- capstone_data.set('CAPSTONE_HAS_ARM64', '1') +- capstone_files += files( +- 'capstone/arch/AArch64/AArch64BaseInfo.c', +- 'capstone/arch/AArch64/AArch64Disassembler.c', +- 'capstone/arch/AArch64/AArch64InstPrinter.c', +- 'capstone/arch/AArch64/AArch64Mapping.c', +- 'capstone/arch/AArch64/AArch64Module.c' +- ) +- endif +- +- if 'CONFIG_PPC_DIS' in config_all_disas +- capstone_data.set('CAPSTONE_HAS_POWERPC', '1') +- capstone_files += files( +- 'capstone/arch/PowerPC/PPCDisassembler.c', +- 'capstone/arch/PowerPC/PPCInstPrinter.c', +- 'capstone/arch/PowerPC/PPCMapping.c', +- 'capstone/arch/PowerPC/PPCModule.c' +- ) +- endif +- +- if 'CONFIG_S390_DIS' in config_all_disas +- capstone_data.set('CAPSTONE_HAS_SYSZ', '1') +- capstone_files += files( +- 'capstone/arch/SystemZ/SystemZDisassembler.c', +- 'capstone/arch/SystemZ/SystemZInstPrinter.c', +- 'capstone/arch/SystemZ/SystemZMapping.c', +- 'capstone/arch/SystemZ/SystemZModule.c', +- 'capstone/arch/SystemZ/SystemZMCTargetDesc.c' +- ) +- endif +- +- if 'CONFIG_I386_DIS' in config_all_disas +- capstone_data.set('CAPSTONE_HAS_X86', 1) +- capstone_files += files( +- 'capstone/arch/X86/X86Disassembler.c', +- 'capstone/arch/X86/X86DisassemblerDecoder.c', +- 'capstone/arch/X86/X86ATTInstPrinter.c', +- 'capstone/arch/X86/X86IntelInstPrinter.c', +- 'capstone/arch/X86/X86InstPrinterCommon.c', +- 'capstone/arch/X86/X86Mapping.c', +- 'capstone/arch/X86/X86Module.c' +- ) +- endif +- +- configure_file(output: 'capstone-defs.h', configuration: capstone_data) +- +- capstone_cargs = [ +- # FIXME: There does not seem to be a way to completely replace the c_args +- # that come from add_project_arguments() -- we can only add to them. +- # So: disable all warnings with a big hammer. +- '-Wno-error', '-w', +- +- # Include all configuration defines via a header file, which will wind up +- # as a dependency on the object file, and thus changes here will result +- # in a rebuild. +- '-include', 'capstone-defs.h', +- +- '-Wp,-D_GLIBCXX_ASSERTIONS', +- +- ] +- +- libcapstone = static_library('capstone', +- build_by_default: false, +- sources: capstone_files, +- c_args: capstone_cargs, +- include_directories: 'capstone/include') +- capstone = declare_dependency(link_with: libcapstone, +- include_directories: 'capstone/include/capstone') + endif + + slirp = not_found +@@ -4083,7 +3977,7 @@ summary_info += {'bzip2 support': libbzip2} + summary_info += {'lzfse support': liblzfse} + summary_info += {'zstd support': zstd} + summary_info += {'NUMA host support': numa} +-summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone} ++summary_info += {'capstone': capstone} + summary_info += {'libpmem support': libpmem} + summary_info += {'libdaxctl support': libdaxctl} + summary_info += {'libudev': libudev} +diff --git a/meson_options.txt b/meson_options.txt +index 7cd920fcd6..e58e158396 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -262,8 +262,7 @@ option('libvduse', type: 'feature', value: 'auto', + option('vduse_blk_export', type: 'feature', value: 'auto', + description: 'VDUSE block export support') + +-option('capstone', type: 'combo', value: 'auto', +- choices: ['disabled', 'enabled', 'auto', 'system', 'internal'], ++option('capstone', type: 'feature', value: 'auto', + description: 'Whether and how to find the capstone library') + option('slirp', type: 'combo', value: 'auto', + choices: ['disabled', 'enabled', 'auto', 'system', 'internal'], +diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh +index b1001aa1db..359b04e0e6 100644 +--- a/scripts/meson-buildoptions.sh ++++ b/scripts/meson-buildoptions.sh +@@ -16,9 +16,6 @@ meson_options_help() { + printf "%s\n" ' --enable-block-drv-whitelist-in-tools' + printf "%s\n" ' use block whitelist also in tools instead of only' + printf "%s\n" ' QEMU' +- printf "%s\n" ' --enable-capstone[=CHOICE]' +- printf "%s\n" ' Whether and how to find the capstone library' +- printf "%s\n" ' (choices: auto/disabled/enabled/internal/system)' + printf "%s\n" ' --enable-cfi Control-Flow Integrity (CFI)' + printf "%s\n" ' --enable-cfi-debug Verbose errors in case of CFI violation' + printf "%s\n" ' --enable-debug-mutex mutex debugging support' +@@ -78,6 +75,7 @@ meson_options_help() { + printf "%s\n" ' bzip2 bzip2 support for DMG images' + printf "%s\n" ' canokey CanoKey support' + printf "%s\n" ' cap-ng cap_ng support' ++ printf "%s\n" ' capstone Whether and how to find the capstone library' + printf "%s\n" ' cloop cloop image format support' + printf "%s\n" ' cocoa Cocoa user interface (macOS only)' + printf "%s\n" ' coreaudio CoreAudio sound support' +@@ -218,7 +216,6 @@ _meson_option_parse() { + --disable-cap-ng) printf "%s" -Dcap_ng=disabled ;; + --enable-capstone) printf "%s" -Dcapstone=enabled ;; + --disable-capstone) printf "%s" -Dcapstone=disabled ;; +- --enable-capstone=*) quote_sh "-Dcapstone=$2" ;; + --enable-cfi) printf "%s" -Dcfi=true ;; + --disable-cfi) printf "%s" -Dcfi=false ;; + --enable-cfi-debug) printf "%s" -Dcfi_debug=true ;; +-- +2.31.1 + diff --git a/kvm-i386-do-kvm_put_msr_feature_control-first-thing-when.patch b/kvm-i386-do-kvm_put_msr_feature_control-first-thing-when.patch new file mode 100644 index 0000000..2e9fa92 --- /dev/null +++ b/kvm-i386-do-kvm_put_msr_feature_control-first-thing-when.patch @@ -0,0 +1,66 @@ +From aba2a5cb19efa33be871dd951366439cf99c5f13 Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Thu, 18 Aug 2022 17:01:13 +0200 +Subject: [PATCH 27/29] i386: do kvm_put_msr_feature_control() first thing when + vCPU is reset + +RH-Author: Miroslav Rezanina +RH-MergeRequest: 118: Synchronize qemu-kvm-7.0.0-13.el9 +RH-Bugzilla: 2125281 +RH-Acked-by: Vitaly Kuznetsov +RH-Commit: [2/2] 4986c35a04255c8fe2b62a48f5ea489339f3826a (mrezanin/centos-src-qemu-kvm) + +kvm_put_sregs2() fails to reset 'locked' CR4/CR0 bits upon vCPU reset when +it is in VMX root operation. Do kvm_put_msr_feature_control() before +kvm_put_sregs2() to (possibly) kick vCPU out of VMX root operation. It also +seems logical to do kvm_put_msr_feature_control() before +kvm_put_nested_state() and not after it, especially when 'real' nested +state is set. + +Signed-off-by: Vitaly Kuznetsov +Message-Id: <20220818150113.479917-3-vkuznets@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 45ed68a1a3a19754ade954d75a3c9d13ff560e5c) +Signed-off-by: Vitaly Kuznetsov +--- + target/i386/kvm/kvm.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index fd3237310b..a9eba247a5 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -4533,6 +4533,18 @@ int kvm_arch_put_registers(CPUState *cpu, int level) + + assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu)); + ++ /* ++ * Put MSR_IA32_FEATURE_CONTROL first, this ensures the VM gets out of VMX ++ * root operation upon vCPU reset. kvm_put_msr_feature_control() should also ++ * preceed kvm_put_nested_state() when 'real' nested state is set. ++ */ ++ if (level >= KVM_PUT_RESET_STATE) { ++ ret = kvm_put_msr_feature_control(x86_cpu); ++ if (ret < 0) { ++ return ret; ++ } ++ } ++ + /* must be before kvm_put_nested_state so that EFER.SVME is set */ + ret = has_sregs2 ? kvm_put_sregs2(x86_cpu) : kvm_put_sregs(x86_cpu); + if (ret < 0) { +@@ -4544,11 +4556,6 @@ int kvm_arch_put_registers(CPUState *cpu, int level) + if (ret < 0) { + return ret; + } +- +- ret = kvm_put_msr_feature_control(x86_cpu); +- if (ret < 0) { +- return ret; +- } + } + + if (level == KVM_PUT_FULL_STATE) { +-- +2.31.1 + diff --git a/kvm-i386-reset-KVM-nested-state-upon-CPU-reset.patch b/kvm-i386-reset-KVM-nested-state-upon-CPU-reset.patch new file mode 100644 index 0000000..27ccde7 --- /dev/null +++ b/kvm-i386-reset-KVM-nested-state-upon-CPU-reset.patch @@ -0,0 +1,93 @@ +From 6f650e08efc35cc04730bf99cea7be8d4faa6e74 Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Thu, 18 Aug 2022 17:01:12 +0200 +Subject: [PATCH 26/29] i386: reset KVM nested state upon CPU reset + +RH-Author: Miroslav Rezanina +RH-MergeRequest: 118: Synchronize qemu-kvm-7.0.0-13.el9 +RH-Bugzilla: 2125281 +RH-Acked-by: Vitaly Kuznetsov +RH-Commit: [1/2] b34da74a40fe32ef210c8127ba8bb032aaab6381 (mrezanin/centos-src-qemu-kvm) + +Make sure env->nested_state is cleaned up when a vCPU is reset, it may +be stale after an incoming migration, kvm_arch_put_registers() may +end up failing or putting vCPU in a weird state. + +Reviewed-by: Maxim Levitsky +Signed-off-by: Vitaly Kuznetsov +Message-Id: <20220818150113.479917-2-vkuznets@redhat.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 3cafdb67504a34a0305260f0c86a73d5a3fb000b) +Signed-off-by: Vitaly Kuznetsov +--- + target/i386/kvm/kvm.c | 37 +++++++++++++++++++++++++++---------- + 1 file changed, 27 insertions(+), 10 deletions(-) + +diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c +index 4e5d4bafc4..fd3237310b 100644 +--- a/target/i386/kvm/kvm.c ++++ b/target/i386/kvm/kvm.c +@@ -1695,6 +1695,30 @@ static void kvm_init_xsave(CPUX86State *env) + env->xsave_buf_len); + } + ++static void kvm_init_nested_state(CPUX86State *env) ++{ ++ struct kvm_vmx_nested_state_hdr *vmx_hdr; ++ uint32_t size; ++ ++ if (!env->nested_state) { ++ return; ++ } ++ ++ size = env->nested_state->size; ++ ++ memset(env->nested_state, 0, size); ++ env->nested_state->size = size; ++ ++ if (cpu_has_vmx(env)) { ++ env->nested_state->format = KVM_STATE_NESTED_FORMAT_VMX; ++ vmx_hdr = &env->nested_state->hdr.vmx; ++ vmx_hdr->vmxon_pa = -1ull; ++ vmx_hdr->vmcs12_pa = -1ull; ++ } else if (cpu_has_svm(env)) { ++ env->nested_state->format = KVM_STATE_NESTED_FORMAT_SVM; ++ } ++} ++ + int kvm_arch_init_vcpu(CPUState *cs) + { + struct { +@@ -2122,19 +2146,10 @@ int kvm_arch_init_vcpu(CPUState *cs) + assert(max_nested_state_len >= offsetof(struct kvm_nested_state, data)); + + if (cpu_has_vmx(env) || cpu_has_svm(env)) { +- struct kvm_vmx_nested_state_hdr *vmx_hdr; +- + env->nested_state = g_malloc0(max_nested_state_len); + env->nested_state->size = max_nested_state_len; + +- if (cpu_has_vmx(env)) { +- env->nested_state->format = KVM_STATE_NESTED_FORMAT_VMX; +- vmx_hdr = &env->nested_state->hdr.vmx; +- vmx_hdr->vmxon_pa = -1ull; +- vmx_hdr->vmcs12_pa = -1ull; +- } else { +- env->nested_state->format = KVM_STATE_NESTED_FORMAT_SVM; +- } ++ kvm_init_nested_state(env); + } + } + +@@ -2199,6 +2214,8 @@ void kvm_arch_reset_vcpu(X86CPU *cpu) + /* enabled by default */ + env->poll_control_msr = 1; + ++ kvm_init_nested_state(env); ++ + sev_es_set_reset_vector(CPU(cpu)); + } + +-- +2.31.1 + diff --git a/kvm-util-accept-iova_tree_remove_parameter-by-value.patch b/kvm-util-accept-iova_tree_remove_parameter-by-value.patch new file mode 100644 index 0000000..5cd76c3 --- /dev/null +++ b/kvm-util-accept-iova_tree_remove_parameter-by-value.patch @@ -0,0 +1,182 @@ +From 3320d1883222bc551cf8ffd048882be4a97e872f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:20:04 +0200 +Subject: [PATCH 03/29] util: accept iova_tree_remove_parameter by value +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [3/25] 98190376f758aed31bc31ce3e478438787eb357c (redhat/centos-stream/src/qemu-kvm) + +It's convenient to call iova_tree_remove from a map returned from +iova_tree_find or iova_tree_find_iova. With the current code this is not +possible, since we will free it, and then we will try to search for it +again. + +Fix it making accepting the map by value, forcing a copy of the +argument. Not applying a fixes tag, since there is no use like that at +the moment. + +Signed-off-by: Eugenio Pérez +Signed-off-by: Jason Wang +(cherry picked from commit 69292a8e40f4dae8af5f04724e06392cdf03c09e) +Signed-off-by: Laurent Vivier +--- + hw/i386/intel_iommu.c | 6 +++--- + hw/virtio/vhost-iova-tree.c | 2 +- + hw/virtio/vhost-iova-tree.h | 2 +- + hw/virtio/vhost-vdpa.c | 6 +++--- + include/qemu/iova-tree.h | 2 +- + net/vhost-vdpa.c | 4 ++-- + util/iova-tree.c | 4 ++-- + 7 files changed, 13 insertions(+), 13 deletions(-) + +diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c +index 2162394e08..05d53a1aa9 100644 +--- a/hw/i386/intel_iommu.c ++++ b/hw/i386/intel_iommu.c +@@ -1187,7 +1187,7 @@ static int vtd_page_walk_one(IOMMUTLBEvent *event, vtd_page_walk_info *info) + return ret; + } + /* Drop any existing mapping */ +- iova_tree_remove(as->iova_tree, &target); ++ iova_tree_remove(as->iova_tree, target); + /* Recover the correct type */ + event->type = IOMMU_NOTIFIER_MAP; + entry->perm = cache_perm; +@@ -1200,7 +1200,7 @@ static int vtd_page_walk_one(IOMMUTLBEvent *event, vtd_page_walk_info *info) + trace_vtd_page_walk_one_skip_unmap(entry->iova, entry->addr_mask); + return 0; + } +- iova_tree_remove(as->iova_tree, &target); ++ iova_tree_remove(as->iova_tree, target); + } + + trace_vtd_page_walk_one(info->domain_id, entry->iova, +@@ -3563,7 +3563,7 @@ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n) + + map.iova = n->start; + map.size = size; +- iova_tree_remove(as->iova_tree, &map); ++ iova_tree_remove(as->iova_tree, map); + } + + static void vtd_address_space_unmap_all(IntelIOMMUState *s) +diff --git a/hw/virtio/vhost-iova-tree.c b/hw/virtio/vhost-iova-tree.c +index 67bf6d57ab..3d03395a77 100644 +--- a/hw/virtio/vhost-iova-tree.c ++++ b/hw/virtio/vhost-iova-tree.c +@@ -104,7 +104,7 @@ int vhost_iova_tree_map_alloc(VhostIOVATree *tree, DMAMap *map) + * @iova_tree: The vhost iova tree + * @map: The map to remove + */ +-void vhost_iova_tree_remove(VhostIOVATree *iova_tree, const DMAMap *map) ++void vhost_iova_tree_remove(VhostIOVATree *iova_tree, DMAMap map) + { + iova_tree_remove(iova_tree->iova_taddr_map, map); + } +diff --git a/hw/virtio/vhost-iova-tree.h b/hw/virtio/vhost-iova-tree.h +index 6a4f24e0f9..4adfd79ff0 100644 +--- a/hw/virtio/vhost-iova-tree.h ++++ b/hw/virtio/vhost-iova-tree.h +@@ -22,6 +22,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostIOVATree, vhost_iova_tree_delete); + const DMAMap *vhost_iova_tree_find_iova(const VhostIOVATree *iova_tree, + const DMAMap *map); + int vhost_iova_tree_map_alloc(VhostIOVATree *iova_tree, DMAMap *map); +-void vhost_iova_tree_remove(VhostIOVATree *iova_tree, const DMAMap *map); ++void vhost_iova_tree_remove(VhostIOVATree *iova_tree, DMAMap map); + + #endif +diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c +index 7e28d2f674..87e0ad393f 100644 +--- a/hw/virtio/vhost-vdpa.c ++++ b/hw/virtio/vhost-vdpa.c +@@ -240,7 +240,7 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener, + + fail_map: + if (v->shadow_vqs_enabled) { +- vhost_iova_tree_remove(v->iova_tree, &mem_region); ++ vhost_iova_tree_remove(v->iova_tree, mem_region); + } + + fail: +@@ -300,7 +300,7 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener, + return; + } + iova = result->iova; +- vhost_iova_tree_remove(v->iova_tree, result); ++ vhost_iova_tree_remove(v->iova_tree, *result); + } + vhost_vdpa_iotlb_batch_begin_once(v); + ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize)); +@@ -944,7 +944,7 @@ static bool vhost_vdpa_svq_map_ring(struct vhost_vdpa *v, DMAMap *needle, + needle->perm == IOMMU_RO); + if (unlikely(r != 0)) { + error_setg_errno(errp, -r, "Cannot map region to device"); +- vhost_iova_tree_remove(v->iova_tree, needle); ++ vhost_iova_tree_remove(v->iova_tree, *needle); + } + + return r == 0; +diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h +index 16bbfdf5f8..8528e5c98f 100644 +--- a/include/qemu/iova-tree.h ++++ b/include/qemu/iova-tree.h +@@ -73,7 +73,7 @@ int iova_tree_insert(IOVATree *tree, const DMAMap *map); + * all the mappings that are included in the provided range will be + * removed from the tree. Here map->translated_addr is meaningless. + */ +-void iova_tree_remove(IOVATree *tree, const DMAMap *map); ++void iova_tree_remove(IOVATree *tree, DMAMap map); + + /** + * iova_tree_find: +diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c +index 303447a68e..a49e7e649d 100644 +--- a/net/vhost-vdpa.c ++++ b/net/vhost-vdpa.c +@@ -244,7 +244,7 @@ static void vhost_vdpa_cvq_unmap_buf(struct vhost_vdpa *v, void *addr) + error_report("Device cannot unmap: %s(%d)", g_strerror(r), r); + } + +- vhost_iova_tree_remove(tree, map); ++ vhost_iova_tree_remove(tree, *map); + } + + static size_t vhost_vdpa_net_cvq_cmd_len(void) +@@ -297,7 +297,7 @@ static bool vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v, + return true; + + dma_map_err: +- vhost_iova_tree_remove(v->iova_tree, &map); ++ vhost_iova_tree_remove(v->iova_tree, map); + return false; + } + +diff --git a/util/iova-tree.c b/util/iova-tree.c +index fee530a579..536789797e 100644 +--- a/util/iova-tree.c ++++ b/util/iova-tree.c +@@ -164,11 +164,11 @@ void iova_tree_foreach(IOVATree *tree, iova_tree_iterator iterator) + g_tree_foreach(tree->tree, iova_tree_traverse, iterator); + } + +-void iova_tree_remove(IOVATree *tree, const DMAMap *map) ++void iova_tree_remove(IOVATree *tree, DMAMap map) + { + const DMAMap *overlap; + +- while ((overlap = iova_tree_find(tree, map))) { ++ while ((overlap = iova_tree_find(tree, &map))) { + g_tree_remove(tree->tree, overlap); + } + } +-- +2.31.1 + diff --git a/kvm-vdpa-Add-vhost_vdpa_net_load_mq.patch b/kvm-vdpa-Add-vhost_vdpa_net_load_mq.patch new file mode 100644 index 0000000..423cff9 --- /dev/null +++ b/kvm-vdpa-Add-vhost_vdpa_net_load_mq.patch @@ -0,0 +1,74 @@ +From 466adb0e641f5c918cbea84e962ae9352f440663 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Thu, 11 Aug 2022 14:28:47 +0200 +Subject: [PATCH 22/29] vdpa: Add vhost_vdpa_net_load_mq +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [22/25] 01e861ad39d6b8e15870296f508726565101213b (redhat/centos-stream/src/qemu-kvm) + +Upstream: Not merged yet + +Same way as with the MAC, restore the expected number of queues at +device's start. + +Signed-off-by: Eugenio Pérez +Signed-off-by: Laurent Vivier +--- + net/vhost-vdpa.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c +index e799e744cd..3950e4f25d 100644 +--- a/net/vhost-vdpa.c ++++ b/net/vhost-vdpa.c +@@ -400,6 +400,28 @@ static int vhost_vdpa_net_load_mac(VhostVDPAState *s, const VirtIONet *n) + return 0; + } + ++static int vhost_vdpa_net_load_mq(VhostVDPAState *s, ++ const VirtIONet *n) ++{ ++ struct virtio_net_ctrl_mq mq; ++ uint64_t features = n->parent_obj.guest_features; ++ ssize_t dev_written; ++ ++ if (!(features & BIT_ULL(VIRTIO_NET_F_MQ))) { ++ return 0; ++ } ++ ++ mq.virtqueue_pairs = cpu_to_le16(n->curr_queue_pairs); ++ dev_written = vhost_vdpa_net_load_cmd(s, VIRTIO_NET_CTRL_MQ, ++ VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, &mq, ++ sizeof(mq)); ++ if (unlikely(dev_written < 0)) { ++ return dev_written; ++ } ++ ++ return *s->status != VIRTIO_NET_OK; ++} ++ + static int vhost_vdpa_net_load(NetClientState *nc) + { + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); +@@ -418,6 +440,10 @@ static int vhost_vdpa_net_load(NetClientState *nc) + if (unlikely(r < 0)) { + return r; + } ++ r = vhost_vdpa_net_load_mq(s, n); ++ if (unlikely(r)) { ++ return r; ++ } + + return 0; + } +-- +2.31.1 + diff --git a/kvm-vdpa-Add-virtio-net-mac-address-via-CVQ-at-start.patch b/kvm-vdpa-Add-virtio-net-mac-address-via-CVQ-at-start.patch new file mode 100644 index 0000000..c338a29 --- /dev/null +++ b/kvm-vdpa-Add-virtio-net-mac-address-via-CVQ-at-start.patch @@ -0,0 +1,87 @@ +From 10157c62f06e86f2ccf1fd4130ef55f7f9beac2f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:30:36 +0200 +Subject: [PATCH 18/29] vdpa: Add virtio-net mac address via CVQ at start +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [18/25] f5b7a59a70e51450df8c58b48e4eb30ef2a44189 (redhat/centos-stream/src/qemu-kvm) + +This is needed so the destination vdpa device see the same state a the +guest set in the source. + +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit dd036d8d278e6882803bccaa8c51b8527ea33f45) +Signed-off-by: Laurent Vivier +--- + net/vhost-vdpa.c | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c +index 3575bf64ee..640434d1ea 100644 +--- a/net/vhost-vdpa.c ++++ b/net/vhost-vdpa.c +@@ -363,11 +363,51 @@ static ssize_t vhost_vdpa_net_cvq_add(VhostVDPAState *s, size_t out_len, + return vhost_svq_poll(svq); + } + ++static int vhost_vdpa_net_load(NetClientState *nc) ++{ ++ VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); ++ const struct vhost_vdpa *v = &s->vhost_vdpa; ++ const VirtIONet *n; ++ uint64_t features; ++ ++ assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); ++ ++ if (!v->shadow_vqs_enabled) { ++ return 0; ++ } ++ ++ n = VIRTIO_NET(v->dev->vdev); ++ features = n->parent_obj.guest_features; ++ if (features & BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR)) { ++ const struct virtio_net_ctrl_hdr ctrl = { ++ .class = VIRTIO_NET_CTRL_MAC, ++ .cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET, ++ }; ++ char *cursor = s->cvq_cmd_out_buffer; ++ ssize_t dev_written; ++ ++ memcpy(cursor, &ctrl, sizeof(ctrl)); ++ cursor += sizeof(ctrl); ++ memcpy(cursor, n->mac, sizeof(n->mac)); ++ ++ dev_written = vhost_vdpa_net_cvq_add(s, sizeof(ctrl) + sizeof(n->mac), ++ sizeof(virtio_net_ctrl_ack)); ++ if (unlikely(dev_written < 0)) { ++ return dev_written; ++ } ++ ++ return *((virtio_net_ctrl_ack *)s->cvq_cmd_in_buffer) != VIRTIO_NET_OK; ++ } ++ ++ return 0; ++} ++ + static NetClientInfo net_vhost_vdpa_cvq_info = { + .type = NET_CLIENT_DRIVER_VHOST_VDPA, + .size = sizeof(VhostVDPAState), + .receive = vhost_vdpa_receive, + .start = vhost_vdpa_net_cvq_start, ++ .load = vhost_vdpa_net_load, + .stop = vhost_vdpa_net_cvq_stop, + .cleanup = vhost_vdpa_cleanup, + .has_vnet_hdr = vhost_vdpa_has_vnet_hdr, +-- +2.31.1 + diff --git a/kvm-vdpa-Allow-MQ-feature-in-SVQ.patch b/kvm-vdpa-Allow-MQ-feature-in-SVQ.patch new file mode 100644 index 0000000..1d308aa --- /dev/null +++ b/kvm-vdpa-Allow-MQ-feature-in-SVQ.patch @@ -0,0 +1,41 @@ +From 4a1688ed7d06aef31ef48a018b1f4be7690481fd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Thu, 11 Aug 2022 14:54:22 +0200 +Subject: [PATCH 25/29] vdpa: Allow MQ feature in SVQ +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [25/25] e416f00fdbcf7af3ddd504e76519510e3bdc57b7 (redhat/centos-stream/src/qemu-kvm) + +Upstream: Not merged yet + +Finally enable SVQ with MQ feature. + +Signed-off-by: Eugenio Pérez +Signed-off-by: Laurent Vivier +--- + net/vhost-vdpa.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c +index c6cbe2fb5c..4bc3fd01a8 100644 +--- a/net/vhost-vdpa.c ++++ b/net/vhost-vdpa.c +@@ -94,6 +94,7 @@ static const uint64_t vdpa_svq_device_features = + BIT_ULL(VIRTIO_NET_F_MRG_RXBUF) | + BIT_ULL(VIRTIO_NET_F_STATUS) | + BIT_ULL(VIRTIO_NET_F_CTRL_VQ) | ++ BIT_ULL(VIRTIO_NET_F_MQ) | + BIT_ULL(VIRTIO_F_ANY_LAYOUT) | + BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR) | + BIT_ULL(VIRTIO_NET_F_RSC_EXT) | +-- +2.31.1 + diff --git a/kvm-vdpa-Delete-CVQ-migration-blocker.patch b/kvm-vdpa-Delete-CVQ-migration-blocker.patch new file mode 100644 index 0000000..f99983b --- /dev/null +++ b/kvm-vdpa-Delete-CVQ-migration-blocker.patch @@ -0,0 +1,98 @@ +From caa8a1d41ca1f2b9c4d1c6cc287c8ae22063b488 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:30:37 +0200 +Subject: [PATCH 19/29] vdpa: Delete CVQ migration blocker +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [19/25] d3e6c009f66e1dc0069323684af28936ae10d155 (redhat/centos-stream/src/qemu-kvm) + +We can restore the device state in the destination via CVQ now. Remove +the migration blocker. + +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit 0e3fdcffead7c651ce06ab50cffb89e806f04e2b) +Signed-off-by: Laurent Vivier +--- + hw/virtio/vhost-vdpa.c | 15 --------------- + include/hw/virtio/vhost-vdpa.h | 1 - + net/vhost-vdpa.c | 2 -- + 3 files changed, 18 deletions(-) + +diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c +index 23ae5ef48b..7468e44b87 100644 +--- a/hw/virtio/vhost-vdpa.c ++++ b/hw/virtio/vhost-vdpa.c +@@ -1033,13 +1033,6 @@ static bool vhost_vdpa_svqs_start(struct vhost_dev *dev) + return true; + } + +- if (v->migration_blocker) { +- int r = migrate_add_blocker(v->migration_blocker, &err); +- if (unlikely(r < 0)) { +- return false; +- } +- } +- + for (i = 0; i < v->shadow_vqs->len; ++i) { + VirtQueue *vq = virtio_get_queue(dev->vdev, dev->vq_index + i); + VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); +@@ -1082,10 +1075,6 @@ err: + vhost_svq_stop(svq); + } + +- if (v->migration_blocker) { +- migrate_del_blocker(v->migration_blocker); +- } +- + return false; + } + +@@ -1101,10 +1090,6 @@ static void vhost_vdpa_svqs_stop(struct vhost_dev *dev) + VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); + vhost_vdpa_svq_unmap_rings(dev, svq); + } +- +- if (v->migration_blocker) { +- migrate_del_blocker(v->migration_blocker); +- } + } + + static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started) +diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h +index d10a89303e..1111d85643 100644 +--- a/include/hw/virtio/vhost-vdpa.h ++++ b/include/hw/virtio/vhost-vdpa.h +@@ -35,7 +35,6 @@ typedef struct vhost_vdpa { + bool shadow_vqs_enabled; + /* IOVA mapping used by the Shadow Virtqueue */ + VhostIOVATree *iova_tree; +- Error *migration_blocker; + GPtrArray *shadow_vqs; + const VhostShadowVirtqueueOps *shadow_vq_ops; + void *shadow_vq_ops_opaque; +diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c +index 640434d1ea..6ce68fcd3f 100644 +--- a/net/vhost-vdpa.c ++++ b/net/vhost-vdpa.c +@@ -555,8 +555,6 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, + + s->vhost_vdpa.shadow_vq_ops = &vhost_vdpa_net_svq_ops; + s->vhost_vdpa.shadow_vq_ops_opaque = s; +- error_setg(&s->vhost_vdpa.migration_blocker, +- "Migration disabled: vhost-vdpa uses CVQ."); + } + ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa, queue_pair_index, nvqs); + if (ret) { +-- +2.31.1 + diff --git a/kvm-vdpa-Make-SVQ-vring-unmapping-return-void.patch b/kvm-vdpa-Make-SVQ-vring-unmapping-return-void.patch new file mode 100644 index 0000000..8b6dd7e --- /dev/null +++ b/kvm-vdpa-Make-SVQ-vring-unmapping-return-void.patch @@ -0,0 +1,133 @@ +From 08d9ea9f9218ad628771f3962d52fb4b6c110262 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:20:06 +0200 +Subject: [PATCH 05/29] vdpa: Make SVQ vring unmapping return void +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [5/25] 340a2246e85d30b6d30ab24198af0fb65520276e (redhat/centos-stream/src/qemu-kvm) + +Nothing actually reads the return value, but an error in cleaning some +entries could cause device stop to abort, making a restart impossible. +Better ignore explicitely the return value. + +Reported-by: Lei Yang +Fixes: 34e3c94eda ("vdpa: Add custom IOTLB translations to SVQ") +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit 5b590f51b923776a14d3bcafcb393279c1b72022) +Signed-off-by: Laurent Vivier +--- + hw/virtio/vhost-vdpa.c | 32 ++++++++++---------------------- + 1 file changed, 10 insertions(+), 22 deletions(-) + +diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c +index e16e0e222e..e208dd000e 100644 +--- a/hw/virtio/vhost-vdpa.c ++++ b/hw/virtio/vhost-vdpa.c +@@ -884,7 +884,7 @@ static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev, + /** + * Unmap a SVQ area in the device + */ +-static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, ++static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, + const DMAMap *needle) + { + const DMAMap *result = vhost_iova_tree_find_iova(v->iova_tree, needle); +@@ -893,38 +893,33 @@ static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, + + if (unlikely(!result)) { + error_report("Unable to find SVQ address to unmap"); +- return false; ++ return; + } + + size = ROUND_UP(result->size, qemu_real_host_page_size()); + r = vhost_vdpa_dma_unmap(v, result->iova, size); + if (unlikely(r < 0)) { + error_report("Unable to unmap SVQ vring: %s (%d)", g_strerror(-r), -r); +- return false; ++ return; + } + + vhost_iova_tree_remove(v->iova_tree, *result); +- return r == 0; + } + +-static bool vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev, ++static void vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev, + const VhostShadowVirtqueue *svq) + { + DMAMap needle = {}; + struct vhost_vdpa *v = dev->opaque; + struct vhost_vring_addr svq_addr; +- bool ok; + + vhost_svq_get_vring_addr(svq, &svq_addr); + + needle.translated_addr = svq_addr.desc_user_addr; +- ok = vhost_vdpa_svq_unmap_ring(v, &needle); +- if (unlikely(!ok)) { +- return false; +- } ++ vhost_vdpa_svq_unmap_ring(v, &needle); + + needle.translated_addr = svq_addr.used_user_addr; +- return vhost_vdpa_svq_unmap_ring(v, &needle); ++ vhost_vdpa_svq_unmap_ring(v, &needle); + } + + /** +@@ -1095,26 +1090,22 @@ err: + return false; + } + +-static bool vhost_vdpa_svqs_stop(struct vhost_dev *dev) ++static void vhost_vdpa_svqs_stop(struct vhost_dev *dev) + { + struct vhost_vdpa *v = dev->opaque; + + if (!v->shadow_vqs) { +- return true; ++ return; + } + + for (unsigned i = 0; i < v->shadow_vqs->len; ++i) { + VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i); +- bool ok = vhost_vdpa_svq_unmap_rings(dev, svq); +- if (unlikely(!ok)) { +- return false; +- } ++ vhost_vdpa_svq_unmap_rings(dev, svq); + } + + if (v->migration_blocker) { + migrate_del_blocker(v->migration_blocker); + } +- return true; + } + + static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started) +@@ -1131,10 +1122,7 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started) + } + vhost_vdpa_set_vring_ready(dev); + } else { +- ok = vhost_vdpa_svqs_stop(dev); +- if (unlikely(!ok)) { +- return -1; +- } ++ vhost_vdpa_svqs_stop(dev); + vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs); + } + +-- +2.31.1 + diff --git a/kvm-vdpa-Make-VhostVDPAState-cvq_cmd_in_buffer-control-a.patch b/kvm-vdpa-Make-VhostVDPAState-cvq_cmd_in_buffer-control-a.patch new file mode 100644 index 0000000..c762cf4 --- /dev/null +++ b/kvm-vdpa-Make-VhostVDPAState-cvq_cmd_in_buffer-control-a.patch @@ -0,0 +1,113 @@ +From d44701ad634f05c31a1b0f0b84b168ed1ec19f71 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Wed, 24 Aug 2022 20:28:35 +0200 +Subject: [PATCH 20/29] vdpa: Make VhostVDPAState cvq_cmd_in_buffer control ack + type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [20/25] fd7012502f7002f61ea2e0c90baac013e09282de (redhat/centos-stream/src/qemu-kvm) + +Upstream: Not merged yet + +This allows to simplify the code. Rename to status while we're at it. + +Signed-off-by: Eugenio Pérez +Signed-off-by: Laurent Vivier +--- + net/vhost-vdpa.c | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c +index 6ce68fcd3f..535315c1d0 100644 +--- a/net/vhost-vdpa.c ++++ b/net/vhost-vdpa.c +@@ -35,7 +35,9 @@ typedef struct VhostVDPAState { + VHostNetState *vhost_net; + + /* Control commands shadow buffers */ +- void *cvq_cmd_out_buffer, *cvq_cmd_in_buffer; ++ void *cvq_cmd_out_buffer; ++ virtio_net_ctrl_ack *status; ++ + bool started; + } VhostVDPAState; + +@@ -158,7 +160,7 @@ static void vhost_vdpa_cleanup(NetClientState *nc) + struct vhost_dev *dev = &s->vhost_net->dev; + + qemu_vfree(s->cvq_cmd_out_buffer); +- qemu_vfree(s->cvq_cmd_in_buffer); ++ qemu_vfree(s->status); + if (dev->vq_index + dev->nvqs == dev->vq_index_end) { + g_clear_pointer(&s->vhost_vdpa.iova_tree, vhost_iova_tree_delete); + } +@@ -310,7 +312,7 @@ static int vhost_vdpa_net_cvq_start(NetClientState *nc) + return r; + } + +- r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->cvq_cmd_in_buffer, ++ r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->status, + vhost_vdpa_net_cvq_cmd_page_len(), true); + if (unlikely(r < 0)) { + vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer); +@@ -327,7 +329,7 @@ static void vhost_vdpa_net_cvq_stop(NetClientState *nc) + + if (s->vhost_vdpa.shadow_vqs_enabled) { + vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer); +- vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_in_buffer); ++ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->status); + } + } + +@@ -340,7 +342,7 @@ static ssize_t vhost_vdpa_net_cvq_add(VhostVDPAState *s, size_t out_len, + .iov_len = out_len, + }; + const struct iovec in = { +- .iov_base = s->cvq_cmd_in_buffer, ++ .iov_base = s->status, + .iov_len = sizeof(virtio_net_ctrl_ack), + }; + VhostShadowVirtqueue *svq = g_ptr_array_index(s->vhost_vdpa.shadow_vqs, 0); +@@ -396,7 +398,7 @@ static int vhost_vdpa_net_load(NetClientState *nc) + return dev_written; + } + +- return *((virtio_net_ctrl_ack *)s->cvq_cmd_in_buffer) != VIRTIO_NET_OK; ++ return *s->status != VIRTIO_NET_OK; + } + + return 0; +@@ -491,8 +493,7 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, + goto out; + } + +- memcpy(&status, s->cvq_cmd_in_buffer, sizeof(status)); +- if (status != VIRTIO_NET_OK) { ++ if (*s->status != VIRTIO_NET_OK) { + return VIRTIO_NET_ERR; + } + +@@ -549,9 +550,9 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, + s->cvq_cmd_out_buffer = qemu_memalign(qemu_real_host_page_size(), + vhost_vdpa_net_cvq_cmd_page_len()); + memset(s->cvq_cmd_out_buffer, 0, vhost_vdpa_net_cvq_cmd_page_len()); +- s->cvq_cmd_in_buffer = qemu_memalign(qemu_real_host_page_size(), +- vhost_vdpa_net_cvq_cmd_page_len()); +- memset(s->cvq_cmd_in_buffer, 0, vhost_vdpa_net_cvq_cmd_page_len()); ++ s->status = qemu_memalign(qemu_real_host_page_size(), ++ vhost_vdpa_net_cvq_cmd_page_len()); ++ memset(s->status, 0, vhost_vdpa_net_cvq_cmd_page_len()); + + s->vhost_vdpa.shadow_vq_ops = &vhost_vdpa_net_svq_ops; + s->vhost_vdpa.shadow_vq_ops_opaque = s; +-- +2.31.1 + diff --git a/kvm-vdpa-Move-command-buffers-map-to-start-of-net-device.patch b/kvm-vdpa-Move-command-buffers-map-to-start-of-net-device.patch new file mode 100644 index 0000000..ab07d88 --- /dev/null +++ b/kvm-vdpa-Move-command-buffers-map-to-start-of-net-device.patch @@ -0,0 +1,251 @@ +From 0c03e18c49b62241d046ecb15c0ee3e7f9c2e547 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:30:33 +0200 +Subject: [PATCH 15/29] vdpa: Move command buffers map to start of net device +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [15/25] 216c18aa307f7bdef1575f581b767b6f023a73bd (redhat/centos-stream/src/qemu-kvm) + +As this series will reuse them to restore the device state at the end of +a migration (or a device start), let's allocate only once at the device +start so we don't duplicate their map and unmap. + +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit 7a7f87e94c4e75ca177564491595dd17b7e41a62) +Signed-off-by: Laurent Vivier +--- + net/vhost-vdpa.c | 123 ++++++++++++++++++++++------------------------- + 1 file changed, 58 insertions(+), 65 deletions(-) + +diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c +index 1a597c2e92..452d10ed93 100644 +--- a/net/vhost-vdpa.c ++++ b/net/vhost-vdpa.c +@@ -263,29 +263,20 @@ static size_t vhost_vdpa_net_cvq_cmd_page_len(void) + return ROUND_UP(vhost_vdpa_net_cvq_cmd_len(), qemu_real_host_page_size()); + } + +-/** Copy and map a guest buffer. */ +-static bool vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v, +- const struct iovec *out_data, +- size_t out_num, size_t data_len, void *buf, +- size_t *written, bool write) ++/** Map CVQ buffer. */ ++static int vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v, void *buf, size_t size, ++ bool write) + { + DMAMap map = {}; + int r; + +- if (unlikely(!data_len)) { +- qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid legnth of %s buffer\n", +- __func__, write ? "in" : "out"); +- return false; +- } +- +- *written = iov_to_buf(out_data, out_num, 0, buf, data_len); + map.translated_addr = (hwaddr)(uintptr_t)buf; +- map.size = vhost_vdpa_net_cvq_cmd_page_len() - 1; ++ map.size = size - 1; + map.perm = write ? IOMMU_RW : IOMMU_RO, + r = vhost_iova_tree_map_alloc(v->iova_tree, &map); + if (unlikely(r != IOVA_OK)) { + error_report("Cannot map injected element"); +- return false; ++ return r; + } + + r = vhost_vdpa_dma_map(v, map.iova, vhost_vdpa_net_cvq_cmd_page_len(), buf, +@@ -294,50 +285,58 @@ static bool vhost_vdpa_cvq_map_buf(struct vhost_vdpa *v, + goto dma_map_err; + } + +- return true; ++ return 0; + + dma_map_err: + vhost_iova_tree_remove(v->iova_tree, map); +- return false; ++ return r; + } + +-/** +- * Copy the guest element into a dedicated buffer suitable to be sent to NIC +- * +- * @iov: [0] is the out buffer, [1] is the in one +- */ +-static bool vhost_vdpa_net_cvq_map_elem(VhostVDPAState *s, +- VirtQueueElement *elem, +- struct iovec *iov) ++static int vhost_vdpa_net_cvq_start(NetClientState *nc) + { +- size_t in_copied; +- bool ok; ++ VhostVDPAState *s; ++ int r; + +- iov[0].iov_base = s->cvq_cmd_out_buffer; +- ok = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, elem->out_sg, elem->out_num, +- vhost_vdpa_net_cvq_cmd_len(), iov[0].iov_base, +- &iov[0].iov_len, false); +- if (unlikely(!ok)) { +- return false; ++ assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); ++ ++ s = DO_UPCAST(VhostVDPAState, nc, nc); ++ if (!s->vhost_vdpa.shadow_vqs_enabled) { ++ return 0; + } + +- iov[1].iov_base = s->cvq_cmd_in_buffer; +- ok = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, NULL, 0, +- sizeof(virtio_net_ctrl_ack), iov[1].iov_base, +- &in_copied, true); +- if (unlikely(!ok)) { ++ r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer, ++ vhost_vdpa_net_cvq_cmd_page_len(), false); ++ if (unlikely(r < 0)) { ++ return r; ++ } ++ ++ r = vhost_vdpa_cvq_map_buf(&s->vhost_vdpa, s->cvq_cmd_in_buffer, ++ vhost_vdpa_net_cvq_cmd_page_len(), true); ++ if (unlikely(r < 0)) { + vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer); +- return false; + } + +- iov[1].iov_len = sizeof(virtio_net_ctrl_ack); +- return true; ++ return r; ++} ++ ++static void vhost_vdpa_net_cvq_stop(NetClientState *nc) ++{ ++ VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); ++ ++ assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); ++ ++ if (s->vhost_vdpa.shadow_vqs_enabled) { ++ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_out_buffer); ++ vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, s->cvq_cmd_in_buffer); ++ } + } + + static NetClientInfo net_vhost_vdpa_cvq_info = { + .type = NET_CLIENT_DRIVER_VHOST_VDPA, + .size = sizeof(VhostVDPAState), + .receive = vhost_vdpa_receive, ++ .start = vhost_vdpa_net_cvq_start, ++ .stop = vhost_vdpa_net_cvq_stop, + .cleanup = vhost_vdpa_cleanup, + .has_vnet_hdr = vhost_vdpa_has_vnet_hdr, + .has_ufo = vhost_vdpa_has_ufo, +@@ -348,19 +347,17 @@ static NetClientInfo net_vhost_vdpa_cvq_info = { + * Do not forward commands not supported by SVQ. Otherwise, the device could + * accept it and qemu would not know how to update the device model. + */ +-static bool vhost_vdpa_net_cvq_validate_cmd(const struct iovec *out, +- size_t out_num) ++static bool vhost_vdpa_net_cvq_validate_cmd(const void *out_buf, size_t len) + { + struct virtio_net_ctrl_hdr ctrl; +- size_t n; + +- n = iov_to_buf(out, out_num, 0, &ctrl, sizeof(ctrl)); +- if (unlikely(n < sizeof(ctrl))) { ++ if (unlikely(len < sizeof(ctrl))) { + qemu_log_mask(LOG_GUEST_ERROR, +- "%s: invalid legnth of out buffer %zu\n", __func__, n); ++ "%s: invalid legnth of out buffer %zu\n", __func__, len); + return false; + } + ++ memcpy(&ctrl, out_buf, sizeof(ctrl)); + switch (ctrl.class) { + case VIRTIO_NET_CTRL_MAC: + switch (ctrl.cmd) { +@@ -392,10 +389,14 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, + VhostVDPAState *s = opaque; + size_t in_len, dev_written; + virtio_net_ctrl_ack status = VIRTIO_NET_ERR; +- /* out and in buffers sent to the device */ +- struct iovec dev_buffers[2] = { +- { .iov_base = s->cvq_cmd_out_buffer }, +- { .iov_base = s->cvq_cmd_in_buffer }, ++ /* Out buffer sent to both the vdpa device and the device model */ ++ struct iovec out = { ++ .iov_base = s->cvq_cmd_out_buffer, ++ }; ++ /* In buffer sent to the device */ ++ const struct iovec dev_in = { ++ .iov_base = s->cvq_cmd_in_buffer, ++ .iov_len = sizeof(virtio_net_ctrl_ack), + }; + /* in buffer used for device model */ + const struct iovec in = { +@@ -405,17 +406,15 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, + int r = -EINVAL; + bool ok; + +- ok = vhost_vdpa_net_cvq_map_elem(s, elem, dev_buffers); +- if (unlikely(!ok)) { +- goto out; +- } +- +- ok = vhost_vdpa_net_cvq_validate_cmd(&dev_buffers[0], 1); ++ out.iov_len = iov_to_buf(elem->out_sg, elem->out_num, 0, ++ s->cvq_cmd_out_buffer, ++ vhost_vdpa_net_cvq_cmd_len()); ++ ok = vhost_vdpa_net_cvq_validate_cmd(s->cvq_cmd_out_buffer, out.iov_len); + if (unlikely(!ok)) { + goto out; + } + +- r = vhost_svq_add(svq, &dev_buffers[0], 1, &dev_buffers[1], 1, elem); ++ r = vhost_svq_add(svq, &out, 1, &dev_in, 1, elem); + if (unlikely(r != 0)) { + if (unlikely(r == -ENOSPC)) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device queue\n", +@@ -435,13 +434,13 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, + goto out; + } + +- memcpy(&status, dev_buffers[1].iov_base, sizeof(status)); ++ memcpy(&status, s->cvq_cmd_in_buffer, sizeof(status)); + if (status != VIRTIO_NET_OK) { + goto out; + } + + status = VIRTIO_NET_ERR; +- virtio_net_handle_ctrl_iov(svq->vdev, &in, 1, dev_buffers, 1); ++ virtio_net_handle_ctrl_iov(svq->vdev, &in, 1, &out, 1); + if (status != VIRTIO_NET_OK) { + error_report("Bad CVQ processing in model"); + } +@@ -454,12 +453,6 @@ out: + } + vhost_svq_push_elem(svq, elem, MIN(in_len, sizeof(status))); + g_free(elem); +- if (dev_buffers[0].iov_base) { +- vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, dev_buffers[0].iov_base); +- } +- if (dev_buffers[1].iov_base) { +- vhost_vdpa_cvq_unmap_buf(&s->vhost_vdpa, dev_buffers[1].iov_base); +- } + return r; + } + +-- +2.31.1 + diff --git a/kvm-vdpa-Remove-SVQ-vring-from-iova_tree-at-shutdown.patch b/kvm-vdpa-Remove-SVQ-vring-from-iova_tree-at-shutdown.patch new file mode 100644 index 0000000..8c3aae4 --- /dev/null +++ b/kvm-vdpa-Remove-SVQ-vring-from-iova_tree-at-shutdown.patch @@ -0,0 +1,49 @@ +From dae6d9efac6d7307ccd1e1bebf0a14014f2a4f34 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:20:05 +0200 +Subject: [PATCH 04/29] vdpa: Remove SVQ vring from iova_tree at shutdown +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [4/25] 813fb80fc3c9872729e6b345e1e9209548aa7481 (redhat/centos-stream/src/qemu-kvm) + +Although the device will be reset before usage, the right thing to do is +to clean it. + +Reported-by: Lei Yang +Fixes: 34e3c94eda ("vdpa: Add custom IOTLB translations to SVQ") +Signed-off-by: Eugenio Pérez +Signed-off-by: Jason Wang +(cherry picked from commit b37c12be962f95fd1e93b470a5ff05f6e2035d46) +Signed-off-by: Laurent Vivier +--- + hw/virtio/vhost-vdpa.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c +index 87e0ad393f..e16e0e222e 100644 +--- a/hw/virtio/vhost-vdpa.c ++++ b/hw/virtio/vhost-vdpa.c +@@ -898,6 +898,12 @@ static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, + + size = ROUND_UP(result->size, qemu_real_host_page_size()); + r = vhost_vdpa_dma_unmap(v, result->iova, size); ++ if (unlikely(r < 0)) { ++ error_report("Unable to unmap SVQ vring: %s (%d)", g_strerror(-r), -r); ++ return false; ++ } ++ ++ vhost_iova_tree_remove(v->iova_tree, *result); + return r == 0; + } + +-- +2.31.1 + diff --git a/kvm-vdpa-Skip-the-maps-not-in-the-iova-tree.patch b/kvm-vdpa-Skip-the-maps-not-in-the-iova-tree.patch new file mode 100644 index 0000000..ab58a35 --- /dev/null +++ b/kvm-vdpa-Skip-the-maps-not-in-the-iova-tree.patch @@ -0,0 +1,48 @@ +From 67291df3eca8b3d74567c0e8211c9f7da65e74d4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:20:02 +0200 +Subject: [PATCH 01/29] vdpa: Skip the maps not in the iova tree +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [1/25] d385d5b600ac4f1a9f9fd4f523e5d4078df8478a (redhat/centos-stream/src/qemu-kvm) + +Next patch will skip the registering of dma maps that the vdpa device +rejects in the iova tree. We need to consider that here or we cause a +SIGSEGV accessing result. + +Reported-by: Lei Yang +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit 10dab9f2635b9bab23a2b29974b526e62bb61268) +Signed-off-by: Laurent Vivier +--- + hw/virtio/vhost-vdpa.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c +index 3ff9ce3501..983d3697b0 100644 +--- a/hw/virtio/vhost-vdpa.c ++++ b/hw/virtio/vhost-vdpa.c +@@ -289,6 +289,10 @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener, + }; + + result = vhost_iova_tree_find_iova(v->iova_tree, &mem_region); ++ if (!result) { ++ /* The memory listener map wasn't mapped */ ++ return; ++ } + iova = result->iova; + vhost_iova_tree_remove(v->iova_tree, result); + } +-- +2.31.1 + diff --git a/kvm-vdpa-Use-ring-hwaddr-at-vhost_vdpa_svq_unmap_ring.patch b/kvm-vdpa-Use-ring-hwaddr-at-vhost_vdpa_svq_unmap_ring.patch new file mode 100644 index 0000000..7fdb0e7 --- /dev/null +++ b/kvm-vdpa-Use-ring-hwaddr-at-vhost_vdpa_svq_unmap_ring.patch @@ -0,0 +1,79 @@ +From c91852883439c3a5349f6787b11b7bc71d6504a5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:20:08 +0200 +Subject: [PATCH 07/29] vdpa: Use ring hwaddr at vhost_vdpa_svq_unmap_ring +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [7/25] 961d9854ae1088fc487b32b605fef207aad08924 (redhat/centos-stream/src/qemu-kvm) + +Reduce code duplication. + +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit 8b6d6119ad7fd983d192f60c4960fb6a9197d995) +Signed-off-by: Laurent Vivier +--- + hw/virtio/vhost-vdpa.c | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c +index e208dd000e..23ae5ef48b 100644 +--- a/hw/virtio/vhost-vdpa.c ++++ b/hw/virtio/vhost-vdpa.c +@@ -884,10 +884,12 @@ static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev, + /** + * Unmap a SVQ area in the device + */ +-static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, +- const DMAMap *needle) ++static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, hwaddr addr) + { +- const DMAMap *result = vhost_iova_tree_find_iova(v->iova_tree, needle); ++ const DMAMap needle = { ++ .translated_addr = addr, ++ }; ++ const DMAMap *result = vhost_iova_tree_find_iova(v->iova_tree, &needle); + hwaddr size; + int r; + +@@ -909,17 +911,14 @@ static void vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, + static void vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev, + const VhostShadowVirtqueue *svq) + { +- DMAMap needle = {}; + struct vhost_vdpa *v = dev->opaque; + struct vhost_vring_addr svq_addr; + + vhost_svq_get_vring_addr(svq, &svq_addr); + +- needle.translated_addr = svq_addr.desc_user_addr; +- vhost_vdpa_svq_unmap_ring(v, &needle); ++ vhost_vdpa_svq_unmap_ring(v, svq_addr.desc_user_addr); + +- needle.translated_addr = svq_addr.used_user_addr; +- vhost_vdpa_svq_unmap_ring(v, &needle); ++ vhost_vdpa_svq_unmap_ring(v, svq_addr.used_user_addr); + } + + /** +@@ -997,7 +996,7 @@ static bool vhost_vdpa_svq_map_rings(struct vhost_dev *dev, + ok = vhost_vdpa_svq_map_ring(v, &device_region, errp); + if (unlikely(!ok)) { + error_prepend(errp, "Cannot create vq device region: "); +- vhost_vdpa_svq_unmap_ring(v, &driver_region); ++ vhost_vdpa_svq_unmap_ring(v, driver_region.translated_addr); + } + addr->used_user_addr = device_region.iova; + +-- +2.31.1 + diff --git a/kvm-vdpa-add-net_vhost_vdpa_cvq_info-NetClientInfo.patch b/kvm-vdpa-add-net_vhost_vdpa_cvq_info-NetClientInfo.patch new file mode 100644 index 0000000..1bbfee9 --- /dev/null +++ b/kvm-vdpa-add-net_vhost_vdpa_cvq_info-NetClientInfo.patch @@ -0,0 +1,62 @@ +From a32ab5c3f2156ab098e8914437f1aa00c095450e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:30:32 +0200 +Subject: [PATCH 14/29] vdpa: add net_vhost_vdpa_cvq_info NetClientInfo +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [14/25] 579b8389d759ae973552ade34369318e8c50aa90 (redhat/centos-stream/src/qemu-kvm) + +Next patches will add a new info callback to restore NIC status through +CVQ. Since only the CVQ vhost device is needed, create it with a new +NetClientInfo. + +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit f8972b56eeace10a410990f032406250abe18d64) +Signed-off-by: Laurent Vivier +--- + net/vhost-vdpa.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c +index a49e7e649d..1a597c2e92 100644 +--- a/net/vhost-vdpa.c ++++ b/net/vhost-vdpa.c +@@ -334,6 +334,16 @@ static bool vhost_vdpa_net_cvq_map_elem(VhostVDPAState *s, + return true; + } + ++static NetClientInfo net_vhost_vdpa_cvq_info = { ++ .type = NET_CLIENT_DRIVER_VHOST_VDPA, ++ .size = sizeof(VhostVDPAState), ++ .receive = vhost_vdpa_receive, ++ .cleanup = vhost_vdpa_cleanup, ++ .has_vnet_hdr = vhost_vdpa_has_vnet_hdr, ++ .has_ufo = vhost_vdpa_has_ufo, ++ .check_peer_type = vhost_vdpa_check_peer_type, ++}; ++ + /** + * Do not forward commands not supported by SVQ. Otherwise, the device could + * accept it and qemu would not know how to update the device model. +@@ -475,7 +485,7 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer, + nc = qemu_new_net_client(&net_vhost_vdpa_info, peer, device, + name); + } else { +- nc = qemu_new_net_control_client(&net_vhost_vdpa_info, peer, ++ nc = qemu_new_net_control_client(&net_vhost_vdpa_cvq_info, peer, + device, name); + } + snprintf(nc->info_str, sizeof(nc->info_str), TYPE_VHOST_VDPA); +-- +2.31.1 + diff --git a/kvm-vdpa-do-not-save-failed-dma-maps-in-SVQ-iova-tree.patch b/kvm-vdpa-do-not-save-failed-dma-maps-in-SVQ-iova-tree.patch new file mode 100644 index 0000000..ba35d21 --- /dev/null +++ b/kvm-vdpa-do-not-save-failed-dma-maps-in-SVQ-iova-tree.patch @@ -0,0 +1,83 @@ +From 8b85c33c0efb0c6f2dc3705ee83082438db9d397 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:20:03 +0200 +Subject: [PATCH 02/29] vdpa: do not save failed dma maps in SVQ iova tree +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [2/25] fc285fecfd400702f81345cef445f5218bcbacad (redhat/centos-stream/src/qemu-kvm) + +If a map fails for whatever reason, it must not be saved in the tree. +Otherwise, qemu will try to unmap it in cleanup, leaving to more errors. + +Fixes: 34e3c94eda ("vdpa: Add custom IOTLB translations to SVQ") +Reported-by: Lei Yang +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit 7dab70bec397e3522211e7bcc36d879bad8154c5) +Signed-off-by: Laurent Vivier +--- + hw/virtio/vhost-vdpa.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c +index 983d3697b0..7e28d2f674 100644 +--- a/hw/virtio/vhost-vdpa.c ++++ b/hw/virtio/vhost-vdpa.c +@@ -176,6 +176,7 @@ static void vhost_vdpa_listener_commit(MemoryListener *listener) + static void vhost_vdpa_listener_region_add(MemoryListener *listener, + MemoryRegionSection *section) + { ++ DMAMap mem_region = {}; + struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener); + hwaddr iova; + Int128 llend, llsize; +@@ -212,13 +213,13 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener, + + llsize = int128_sub(llend, int128_make64(iova)); + if (v->shadow_vqs_enabled) { +- DMAMap mem_region = { +- .translated_addr = (hwaddr)(uintptr_t)vaddr, +- .size = int128_get64(llsize) - 1, +- .perm = IOMMU_ACCESS_FLAG(true, section->readonly), +- }; ++ int r; + +- int r = vhost_iova_tree_map_alloc(v->iova_tree, &mem_region); ++ mem_region.translated_addr = (hwaddr)(uintptr_t)vaddr, ++ mem_region.size = int128_get64(llsize) - 1, ++ mem_region.perm = IOMMU_ACCESS_FLAG(true, section->readonly), ++ ++ r = vhost_iova_tree_map_alloc(v->iova_tree, &mem_region); + if (unlikely(r != IOVA_OK)) { + error_report("Can't allocate a mapping (%d)", r); + goto fail; +@@ -232,11 +233,16 @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener, + vaddr, section->readonly); + if (ret) { + error_report("vhost vdpa map fail!"); +- goto fail; ++ goto fail_map; + } + + return; + ++fail_map: ++ if (v->shadow_vqs_enabled) { ++ vhost_iova_tree_remove(v->iova_tree, &mem_region); ++ } ++ + fail: + /* + * On the initfn path, store the first error in the container so we +-- +2.31.1 + diff --git a/kvm-vdpa-extract-vhost_vdpa_net_cvq_add-from-vhost_vdpa_.patch b/kvm-vdpa-extract-vhost_vdpa_net_cvq_add-from-vhost_vdpa_.patch new file mode 100644 index 0000000..7737060 --- /dev/null +++ b/kvm-vdpa-extract-vhost_vdpa_net_cvq_add-from-vhost_vdpa_.patch @@ -0,0 +1,153 @@ +From 09b86938668bf6111fb6549fcd012f50418a7613 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:30:34 +0200 +Subject: [PATCH 16/29] vdpa: extract vhost_vdpa_net_cvq_add from + vhost_vdpa_net_handle_ctrl_avail +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [16/25] 7d577b06dcd889f836d5bcbaf6a64998fb138543 (redhat/centos-stream/src/qemu-kvm) + +So we can reuse it to inject state messages. + +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +-- +v7: +* Remove double free error + +v6: +* Do not assume in buffer sent to the device is sizeof(virtio_net_ctrl_ack) + +v5: +* Do not use an artificial !NULL VirtQueueElement +* Use only out size instead of iovec dev_buffers for these functions. + +Signed-off-by: Jason Wang +(cherry picked from commit be4278b65fc1be8fce87e1e7c01bc52602d304eb) +Signed-off-by: Laurent Vivier +--- + net/vhost-vdpa.c | 59 +++++++++++++++++++++++++++++++----------------- + 1 file changed, 38 insertions(+), 21 deletions(-) + +diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c +index 452d10ed93..3575bf64ee 100644 +--- a/net/vhost-vdpa.c ++++ b/net/vhost-vdpa.c +@@ -331,6 +331,38 @@ static void vhost_vdpa_net_cvq_stop(NetClientState *nc) + } + } + ++static ssize_t vhost_vdpa_net_cvq_add(VhostVDPAState *s, size_t out_len, ++ size_t in_len) ++{ ++ /* Buffers for the device */ ++ const struct iovec out = { ++ .iov_base = s->cvq_cmd_out_buffer, ++ .iov_len = out_len, ++ }; ++ const struct iovec in = { ++ .iov_base = s->cvq_cmd_in_buffer, ++ .iov_len = sizeof(virtio_net_ctrl_ack), ++ }; ++ VhostShadowVirtqueue *svq = g_ptr_array_index(s->vhost_vdpa.shadow_vqs, 0); ++ int r; ++ ++ r = vhost_svq_add(svq, &out, 1, &in, 1, NULL); ++ if (unlikely(r != 0)) { ++ if (unlikely(r == -ENOSPC)) { ++ qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device queue\n", ++ __func__); ++ } ++ return r; ++ } ++ ++ /* ++ * We can poll here since we've had BQL from the time we sent the ++ * descriptor. Also, we need to take the answer before SVQ pulls by itself, ++ * when BQL is released ++ */ ++ return vhost_svq_poll(svq); ++} ++ + static NetClientInfo net_vhost_vdpa_cvq_info = { + .type = NET_CLIENT_DRIVER_VHOST_VDPA, + .size = sizeof(VhostVDPAState), +@@ -387,23 +419,18 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, + void *opaque) + { + VhostVDPAState *s = opaque; +- size_t in_len, dev_written; ++ size_t in_len; + virtio_net_ctrl_ack status = VIRTIO_NET_ERR; + /* Out buffer sent to both the vdpa device and the device model */ + struct iovec out = { + .iov_base = s->cvq_cmd_out_buffer, + }; +- /* In buffer sent to the device */ +- const struct iovec dev_in = { +- .iov_base = s->cvq_cmd_in_buffer, +- .iov_len = sizeof(virtio_net_ctrl_ack), +- }; + /* in buffer used for device model */ + const struct iovec in = { + .iov_base = &status, + .iov_len = sizeof(status), + }; +- int r = -EINVAL; ++ ssize_t dev_written = -EINVAL; + bool ok; + + out.iov_len = iov_to_buf(elem->out_sg, elem->out_num, 0, +@@ -414,21 +441,11 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, + goto out; + } + +- r = vhost_svq_add(svq, &out, 1, &dev_in, 1, elem); +- if (unlikely(r != 0)) { +- if (unlikely(r == -ENOSPC)) { +- qemu_log_mask(LOG_GUEST_ERROR, "%s: No space on device queue\n", +- __func__); +- } ++ dev_written = vhost_vdpa_net_cvq_add(s, out.iov_len, sizeof(status)); ++ if (unlikely(dev_written < 0)) { + goto out; + } + +- /* +- * We can poll here since we've had BQL from the time we sent the +- * descriptor. Also, we need to take the answer before SVQ pulls by itself, +- * when BQL is released +- */ +- dev_written = vhost_svq_poll(svq); + if (unlikely(dev_written < sizeof(status))) { + error_report("Insufficient written data (%zu)", dev_written); + goto out; +@@ -436,7 +453,7 @@ static int vhost_vdpa_net_handle_ctrl_avail(VhostShadowVirtqueue *svq, + + memcpy(&status, s->cvq_cmd_in_buffer, sizeof(status)); + if (status != VIRTIO_NET_OK) { +- goto out; ++ return VIRTIO_NET_ERR; + } + + status = VIRTIO_NET_ERR; +@@ -453,7 +470,7 @@ out: + } + vhost_svq_push_elem(svq, elem, MIN(in_len, sizeof(status))); + g_free(elem); +- return r; ++ return dev_written < 0 ? dev_written : 0; + } + + static const VhostShadowVirtqueueOps vhost_vdpa_net_svq_ops = { +-- +2.31.1 + diff --git a/kvm-vdpa-extract-vhost_vdpa_net_load_mac-from-vhost_vdpa.patch b/kvm-vdpa-extract-vhost_vdpa_net_load_mac-from-vhost_vdpa.patch new file mode 100644 index 0000000..707013a --- /dev/null +++ b/kvm-vdpa-extract-vhost_vdpa_net_load_mac-from-vhost_vdpa.patch @@ -0,0 +1,115 @@ +From e03f7e670e608e98fa771d3860574b95908ef3a1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Thu, 11 Aug 2022 14:12:14 +0200 +Subject: [PATCH 21/29] vdpa: extract vhost_vdpa_net_load_mac from + vhost_vdpa_net_load +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [21/25] b4b30be584aab265004648352361f25587e0ed98 (redhat/centos-stream/src/qemu-kvm) + +Upstream: Not merged yet + +Since there may be many commands we need to issue to load the NIC +state, let's split them in individual functions + +Signed-off-by: Eugenio Pérez +Signed-off-by: Laurent Vivier +--- + net/vhost-vdpa.c | 62 +++++++++++++++++++++++++++++++----------------- + 1 file changed, 40 insertions(+), 22 deletions(-) + +diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c +index 535315c1d0..e799e744cd 100644 +--- a/net/vhost-vdpa.c ++++ b/net/vhost-vdpa.c +@@ -365,12 +365,47 @@ static ssize_t vhost_vdpa_net_cvq_add(VhostVDPAState *s, size_t out_len, + return vhost_svq_poll(svq); + } + ++static ssize_t vhost_vdpa_net_load_cmd(VhostVDPAState *s, uint8_t class, ++ uint8_t cmd, const void *data, ++ size_t data_size) ++{ ++ const struct virtio_net_ctrl_hdr ctrl = { ++ .class = class, ++ .cmd = cmd, ++ }; ++ ++ assert(data_size < vhost_vdpa_net_cvq_cmd_page_len() - sizeof(ctrl)); ++ ++ memcpy(s->cvq_cmd_out_buffer, &ctrl, sizeof(ctrl)); ++ memcpy(s->cvq_cmd_out_buffer + sizeof(ctrl), data, data_size); ++ ++ return vhost_vdpa_net_cvq_add(s, sizeof(ctrl) + data_size, ++ sizeof(virtio_net_ctrl_ack)); ++} ++ ++static int vhost_vdpa_net_load_mac(VhostVDPAState *s, const VirtIONet *n) ++{ ++ uint64_t features = n->parent_obj.guest_features; ++ if (features & BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR)) { ++ ssize_t dev_written = vhost_vdpa_net_load_cmd(s, VIRTIO_NET_CTRL_MAC, ++ VIRTIO_NET_CTRL_MAC_ADDR_SET, ++ n->mac, sizeof(n->mac)); ++ if (unlikely(dev_written < 0)) { ++ return dev_written; ++ } ++ ++ return *s->status != VIRTIO_NET_OK; ++ } ++ ++ return 0; ++} ++ + static int vhost_vdpa_net_load(NetClientState *nc) + { + VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc); +- const struct vhost_vdpa *v = &s->vhost_vdpa; ++ struct vhost_vdpa *v = &s->vhost_vdpa; + const VirtIONet *n; +- uint64_t features; ++ int r; + + assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA); + +@@ -379,26 +414,9 @@ static int vhost_vdpa_net_load(NetClientState *nc) + } + + n = VIRTIO_NET(v->dev->vdev); +- features = n->parent_obj.guest_features; +- if (features & BIT_ULL(VIRTIO_NET_F_CTRL_MAC_ADDR)) { +- const struct virtio_net_ctrl_hdr ctrl = { +- .class = VIRTIO_NET_CTRL_MAC, +- .cmd = VIRTIO_NET_CTRL_MAC_ADDR_SET, +- }; +- char *cursor = s->cvq_cmd_out_buffer; +- ssize_t dev_written; +- +- memcpy(cursor, &ctrl, sizeof(ctrl)); +- cursor += sizeof(ctrl); +- memcpy(cursor, n->mac, sizeof(n->mac)); +- +- dev_written = vhost_vdpa_net_cvq_add(s, sizeof(ctrl) + sizeof(n->mac), +- sizeof(virtio_net_ctrl_ack)); +- if (unlikely(dev_written < 0)) { +- return dev_written; +- } +- +- return *s->status != VIRTIO_NET_OK; ++ r = vhost_vdpa_net_load_mac(s, n); ++ if (unlikely(r < 0)) { ++ return r; + } + + return 0; +-- +2.31.1 + diff --git a/kvm-vdpa-validate-MQ-CVQ-commands.patch b/kvm-vdpa-validate-MQ-CVQ-commands.patch new file mode 100644 index 0000000..2e816eb --- /dev/null +++ b/kvm-vdpa-validate-MQ-CVQ-commands.patch @@ -0,0 +1,50 @@ +From b4a0334826d5b28dd8f63edaa606cc123b60a538 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Thu, 11 Aug 2022 14:53:10 +0200 +Subject: [PATCH 23/29] vdpa: validate MQ CVQ commands +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [23/25] b727a8bba49a364c6c9afe3d7bfcc70e3ee942f4 (redhat/centos-stream/src/qemu-kvm) + +Upstream: Not merged yet + +So we are sure we can update the device model properly before sending to +the device. + +Signed-off-by: Eugenio Pérez +Signed-off-by: Laurent Vivier +--- + net/vhost-vdpa.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c +index 3950e4f25d..c6cbe2fb5c 100644 +--- a/net/vhost-vdpa.c ++++ b/net/vhost-vdpa.c +@@ -486,6 +486,15 @@ static bool vhost_vdpa_net_cvq_validate_cmd(const void *out_buf, size_t len) + __func__, ctrl.cmd); + }; + break; ++ case VIRTIO_NET_CTRL_MQ: ++ switch (ctrl.cmd) { ++ case VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET: ++ return true; ++ default: ++ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid mq cmd %u\n", ++ __func__, ctrl.cmd); ++ }; ++ break; + default: + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid control class %u\n", + __func__, ctrl.class); +-- +2.31.1 + diff --git a/kvm-vhost-Always-store-new-kick-fd-on-vhost_svq_set_svq_.patch b/kvm-vhost-Always-store-new-kick-fd-on-vhost_svq_set_svq_.patch new file mode 100644 index 0000000..b01d7aa --- /dev/null +++ b/kvm-vhost-Always-store-new-kick-fd-on-vhost_svq_set_svq_.patch @@ -0,0 +1,67 @@ +From 88ea456e00f5af59417ef2c397adfea4cf9c685e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:20:07 +0200 +Subject: [PATCH 06/29] vhost: Always store new kick fd on + vhost_svq_set_svq_kick_fd +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [6/25] 1c2ec6d321446505b9f9d0cc0cf0d812cfddd959 (redhat/centos-stream/src/qemu-kvm) + +We can unbind twice a file descriptor if we call twice +vhost_svq_set_svq_kick_fd because of this. Since it comes from vhost and +not from SVQ, that file descriptor could be a different thing that +guest's vhost notifier. + +Likewise, it can happens the same if a guest start and stop the device +multiple times. + +Reported-by: Lei Yang +Fixes: dff4426fa6 ("vhost: Add Shadow VirtQueue kick forwarding capabilities") +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit 8b64e486423b09db4463799727bf1fad62fe496a) +Signed-off-by: Laurent Vivier +--- + hw/virtio/vhost-shadow-virtqueue.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c +index e4956728dd..82a784d250 100644 +--- a/hw/virtio/vhost-shadow-virtqueue.c ++++ b/hw/virtio/vhost-shadow-virtqueue.c +@@ -602,13 +602,13 @@ void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd) + event_notifier_set_handler(svq_kick, NULL); + } + ++ event_notifier_init_fd(svq_kick, svq_kick_fd); + /* + * event_notifier_set_handler already checks for guest's notifications if + * they arrive at the new file descriptor in the switch, so there is no + * need to explicitly check for them. + */ + if (poll_start) { +- event_notifier_init_fd(svq_kick, svq_kick_fd); + event_notifier_set(svq_kick); + event_notifier_set_handler(svq_kick, vhost_handle_guest_kick_notifier); + } +@@ -655,7 +655,7 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, + */ + void vhost_svq_stop(VhostShadowVirtqueue *svq) + { +- event_notifier_set_handler(&svq->svq_kick, NULL); ++ vhost_svq_set_svq_kick_fd(svq, VHOST_FILE_UNBIND); + g_autofree VirtQueueElement *next_avail_elem = NULL; + + if (!svq->vq) { +-- +2.31.1 + diff --git a/kvm-vhost-Delete-useless-read-memory-barrier.patch b/kvm-vhost-Delete-useless-read-memory-barrier.patch new file mode 100644 index 0000000..7938963 --- /dev/null +++ b/kvm-vhost-Delete-useless-read-memory-barrier.patch @@ -0,0 +1,47 @@ +From 878a37760e34b54a3d92569f44b0b2f073bfa46a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:30:28 +0200 +Subject: [PATCH 10/29] vhost: Delete useless read memory barrier +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [10/25] 13fb2b317093323caf33a17f9de00a94a862ca2e (redhat/centos-stream/src/qemu-kvm) + +As discussed in previous series [1], this memory barrier is useless with +the atomic read of used idx at vhost_svq_more_used. Deleting it. + +[1] https://lists.nongnu.org/archive/html/qemu-devel/2022-07/msg02616.html + +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit 9e193cec5db949e4001070442a2f7de7042ef09b) +Signed-off-by: Laurent Vivier +--- + hw/virtio/vhost-shadow-virtqueue.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c +index b35aeef4bd..8df5296f24 100644 +--- a/hw/virtio/vhost-shadow-virtqueue.c ++++ b/hw/virtio/vhost-shadow-virtqueue.c +@@ -509,9 +509,6 @@ size_t vhost_svq_poll(VhostShadowVirtqueue *svq) + if (unlikely(g_get_monotonic_time() - start_us > 10e6)) { + return 0; + } +- +- /* Make sure we read new used_idx */ +- smp_rmb(); + } while (true); + } + +-- +2.31.1 + diff --git a/kvm-vhost-Do-not-depend-on-NULL-VirtQueueElement-on-vhos.patch b/kvm-vhost-Do-not-depend-on-NULL-VirtQueueElement-on-vhos.patch new file mode 100644 index 0000000..858128e --- /dev/null +++ b/kvm-vhost-Do-not-depend-on-NULL-VirtQueueElement-on-vhos.patch @@ -0,0 +1,63 @@ +From 39659fb33b282188f005ba26bd2c40ce8b7a173c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:30:29 +0200 +Subject: [PATCH 11/29] vhost: Do not depend on !NULL VirtQueueElement on + vhost_svq_flush +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [11/25] 2fec9b6bb72cf8ef42d08a28df3dc8b540f6f43f (redhat/centos-stream/src/qemu-kvm) + +Since QEMU will be able to inject new elements on CVQ to restore the +state, we need not to depend on a VirtQueueElement to know if a new +element has been used by the device or not. Instead of check that, check +if there are new elements only using used idx on vhost_svq_flush. + +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit d368c0b052ad95d3bf4fcc5a5d25715a35c91d4b) +Signed-off-by: Laurent Vivier +--- + hw/virtio/vhost-shadow-virtqueue.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c +index 8df5296f24..e8e5bbc368 100644 +--- a/hw/virtio/vhost-shadow-virtqueue.c ++++ b/hw/virtio/vhost-shadow-virtqueue.c +@@ -499,17 +499,20 @@ static void vhost_svq_flush(VhostShadowVirtqueue *svq, + size_t vhost_svq_poll(VhostShadowVirtqueue *svq) + { + int64_t start_us = g_get_monotonic_time(); ++ uint32_t len; ++ + do { +- uint32_t len; +- VirtQueueElement *elem = vhost_svq_get_buf(svq, &len); +- if (elem) { +- return len; ++ if (vhost_svq_more_used(svq)) { ++ break; + } + + if (unlikely(g_get_monotonic_time() - start_us > 10e6)) { + return 0; + } + } while (true); ++ ++ vhost_svq_get_buf(svq, &len); ++ return len; + } + + /** +-- +2.31.1 + diff --git a/kvm-vhost-stop-transfer-elem-ownership-in-vhost_handle_g.patch b/kvm-vhost-stop-transfer-elem-ownership-in-vhost_handle_g.patch new file mode 100644 index 0000000..72707ff --- /dev/null +++ b/kvm-vhost-stop-transfer-elem-ownership-in-vhost_handle_g.patch @@ -0,0 +1,80 @@ +From 33c22dd3353f79a037f2473a69176932ac1a1c05 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:30:26 +0200 +Subject: [PATCH 08/29] vhost: stop transfer elem ownership in + vhost_handle_guest_kick +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [8/25] e9c6314fddeb1f7bc738efea90f2788cae27bab7 (redhat/centos-stream/src/qemu-kvm) + +It was easier to allow vhost_svq_add to handle the memory. Now that we +will allow qemu to add elements to a SVQ without the guest's knowledge, +it's better to handle it in the caller. + +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit 9c2ab2f1ec333be8614cc12272d4b91960704dbe) +Signed-off-by: Laurent Vivier +--- + hw/virtio/vhost-shadow-virtqueue.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c +index 82a784d250..a1261d4a0f 100644 +--- a/hw/virtio/vhost-shadow-virtqueue.c ++++ b/hw/virtio/vhost-shadow-virtqueue.c +@@ -233,9 +233,6 @@ static void vhost_svq_kick(VhostShadowVirtqueue *svq) + /** + * Add an element to a SVQ. + * +- * The caller must check that there is enough slots for the new element. It +- * takes ownership of the element: In case of failure not ENOSPC, it is free. +- * + * Return -EINVAL if element is invalid, -ENOSPC if dev queue is full + */ + int vhost_svq_add(VhostShadowVirtqueue *svq, const struct iovec *out_sg, +@@ -252,7 +249,6 @@ int vhost_svq_add(VhostShadowVirtqueue *svq, const struct iovec *out_sg, + + ok = vhost_svq_add_split(svq, out_sg, out_num, in_sg, in_num, &qemu_head); + if (unlikely(!ok)) { +- g_free(elem); + return -EINVAL; + } + +@@ -293,7 +289,7 @@ static void vhost_handle_guest_kick(VhostShadowVirtqueue *svq) + virtio_queue_set_notification(svq->vq, false); + + while (true) { +- VirtQueueElement *elem; ++ g_autofree VirtQueueElement *elem; + int r; + + if (svq->next_guest_avail_elem) { +@@ -324,12 +320,14 @@ static void vhost_handle_guest_kick(VhostShadowVirtqueue *svq) + * queue the current guest descriptor and ignore kicks + * until some elements are used. + */ +- svq->next_guest_avail_elem = elem; ++ svq->next_guest_avail_elem = g_steal_pointer(&elem); + } + + /* VQ is full or broken, just return and ignore kicks */ + return; + } ++ /* elem belongs to SVQ or external caller now */ ++ elem = NULL; + } + + virtio_queue_set_notification(svq->vq, true); +-- +2.31.1 + diff --git a/kvm-vhost-use-SVQ-element-ndescs-instead-of-opaque-data-.patch b/kvm-vhost-use-SVQ-element-ndescs-instead-of-opaque-data-.patch new file mode 100644 index 0000000..628cc8d --- /dev/null +++ b/kvm-vhost-use-SVQ-element-ndescs-instead-of-opaque-data-.patch @@ -0,0 +1,55 @@ +From cf08dbe33683a66a79ec07b8450f9d3d27cff1c4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:30:27 +0200 +Subject: [PATCH 09/29] vhost: use SVQ element ndescs instead of opaque data + for desc validation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [9/25] 071eb2a0db612d516d630a15a1f0fd908ed86fd3 (redhat/centos-stream/src/qemu-kvm) + +Since we're going to allow SVQ to add elements without the guest's +knowledge and without its own VirtQueueElement, it's easier to check if +an element is a valid head checking a different thing than the +VirtQueueElement. + +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit 86f5f2546f03a3dfde421c715187b262e29b2848) +Signed-off-by: Laurent Vivier +--- + hw/virtio/vhost-shadow-virtqueue.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c +index a1261d4a0f..b35aeef4bd 100644 +--- a/hw/virtio/vhost-shadow-virtqueue.c ++++ b/hw/virtio/vhost-shadow-virtqueue.c +@@ -414,7 +414,7 @@ static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq, + return NULL; + } + +- if (unlikely(!svq->desc_state[used_elem.id].elem)) { ++ if (unlikely(!svq->desc_state[used_elem.id].ndescs)) { + qemu_log_mask(LOG_GUEST_ERROR, + "Device %s says index %u is used, but it was not available", + svq->vdev->name, used_elem.id); +@@ -422,6 +422,7 @@ static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq, + } + + num = svq->desc_state[used_elem.id].ndescs; ++ svq->desc_state[used_elem.id].ndescs = 0; + last_used_chain = vhost_svq_last_desc_of_chain(svq, num, used_elem.id); + svq->desc_next[last_used_chain] = svq->free_head; + svq->free_head = used_elem.id; +-- +2.31.1 + diff --git a/kvm-vhost_net-Add-NetClientInfo-start-callback.patch b/kvm-vhost_net-Add-NetClientInfo-start-callback.patch new file mode 100644 index 0000000..99073b5 --- /dev/null +++ b/kvm-vhost_net-Add-NetClientInfo-start-callback.patch @@ -0,0 +1,73 @@ +From 0db23ec6808c3ff628d1b1940d2cd01fda0757d1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:30:30 +0200 +Subject: [PATCH 12/29] vhost_net: Add NetClientInfo start callback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [12/25] b448657fa858a885879986059694d26d870155bc (redhat/centos-stream/src/qemu-kvm) + +This is used by the backend to perform actions before the device is +started. + +In particular, vdpa net use it to map CVQ buffers to the device, so it +can send control commands using them. + +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit eb92b75380fc0f2368e22be45d1e2d1e2cd2f79c) +Signed-off-by: Laurent Vivier +--- + hw/net/vhost_net.c | 7 +++++++ + include/net/net.h | 2 ++ + 2 files changed, 9 insertions(+) + +diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c +index ccac5b7a64..2e0baeba26 100644 +--- a/hw/net/vhost_net.c ++++ b/hw/net/vhost_net.c +@@ -244,6 +244,13 @@ static int vhost_net_start_one(struct vhost_net *net, + struct vhost_vring_file file = { }; + int r; + ++ if (net->nc->info->start) { ++ r = net->nc->info->start(net->nc); ++ if (r < 0) { ++ return r; ++ } ++ } ++ + r = vhost_dev_enable_notifiers(&net->dev, dev); + if (r < 0) { + goto fail_notifiers; +diff --git a/include/net/net.h b/include/net/net.h +index 523136c7ac..ad9e80083a 100644 +--- a/include/net/net.h ++++ b/include/net/net.h +@@ -44,6 +44,7 @@ typedef struct NICConf { + + typedef void (NetPoll)(NetClientState *, bool enable); + typedef bool (NetCanReceive)(NetClientState *); ++typedef int (NetStart)(NetClientState *); + typedef ssize_t (NetReceive)(NetClientState *, const uint8_t *, size_t); + typedef ssize_t (NetReceiveIOV)(NetClientState *, const struct iovec *, int); + typedef void (NetCleanup) (NetClientState *); +@@ -71,6 +72,7 @@ typedef struct NetClientInfo { + NetReceive *receive_raw; + NetReceiveIOV *receive_iov; + NetCanReceive *can_receive; ++ NetStart *start; + NetCleanup *cleanup; + LinkStatusChanged *link_status_changed; + QueryRxFilter *query_rx_filter; +-- +2.31.1 + diff --git a/kvm-vhost_net-Add-NetClientInfo-stop-callback.patch b/kvm-vhost_net-Add-NetClientInfo-stop-callback.patch new file mode 100644 index 0000000..5b51f8b --- /dev/null +++ b/kvm-vhost_net-Add-NetClientInfo-stop-callback.patch @@ -0,0 +1,68 @@ +From cc3e96b81280fe45a34a26586718079072dbcf39 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:30:31 +0200 +Subject: [PATCH 13/29] vhost_net: Add NetClientInfo stop callback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [13/25] cb90c1228e9af493def4818ea3b49e2b0cfae456 (redhat/centos-stream/src/qemu-kvm) + +Used by the backend to perform actions after the device is stopped. + +In particular, vdpa net use it to unmap CVQ buffers to the device, +cleaning the actions performed in prepare(). + +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit c5e5269d8a955a0f924218911c2f4a0b34e87a21) +Signed-off-by: Laurent Vivier +--- + hw/net/vhost_net.c | 3 +++ + include/net/net.h | 2 ++ + 2 files changed, 5 insertions(+) + +diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c +index 2e0baeba26..9d4b334453 100644 +--- a/hw/net/vhost_net.c ++++ b/hw/net/vhost_net.c +@@ -320,6 +320,9 @@ static void vhost_net_stop_one(struct vhost_net *net, + net->nc->info->poll(net->nc, true); + } + vhost_dev_stop(&net->dev, dev); ++ if (net->nc->info->stop) { ++ net->nc->info->stop(net->nc); ++ } + vhost_dev_disable_notifiers(&net->dev, dev); + } + +diff --git a/include/net/net.h b/include/net/net.h +index ad9e80083a..476ad45b9a 100644 +--- a/include/net/net.h ++++ b/include/net/net.h +@@ -45,6 +45,7 @@ typedef struct NICConf { + typedef void (NetPoll)(NetClientState *, bool enable); + typedef bool (NetCanReceive)(NetClientState *); + typedef int (NetStart)(NetClientState *); ++typedef void (NetStop)(NetClientState *); + typedef ssize_t (NetReceive)(NetClientState *, const uint8_t *, size_t); + typedef ssize_t (NetReceiveIOV)(NetClientState *, const struct iovec *, int); + typedef void (NetCleanup) (NetClientState *); +@@ -73,6 +74,7 @@ typedef struct NetClientInfo { + NetReceiveIOV *receive_iov; + NetCanReceive *can_receive; + NetStart *start; ++ NetStop *stop; + NetCleanup *cleanup; + LinkStatusChanged *link_status_changed; + QueryRxFilter *query_rx_filter; +-- +2.31.1 + diff --git a/kvm-vhost_net-add-NetClientState-load-callback.patch b/kvm-vhost_net-add-NetClientState-load-callback.patch new file mode 100644 index 0000000..ecd279f --- /dev/null +++ b/kvm-vhost_net-add-NetClientState-load-callback.patch @@ -0,0 +1,73 @@ +From d91546b3bc3dd147b6327a4d8c5b523104a09aa6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Tue, 23 Aug 2022 20:30:35 +0200 +Subject: [PATCH 17/29] vhost_net: add NetClientState->load() callback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [17/25] de71f2e8fc7b25f5197101703fbb5ff054ada984 (redhat/centos-stream/src/qemu-kvm) + +It allows per-net client operations right after device's successful +start. In particular, to load the device status. + +Vhost-vdpa net will use it to add the CVQ buffers to restore the device +status. + +Signed-off-by: Eugenio Pérez +Acked-by: Jason Wang +Signed-off-by: Jason Wang +(cherry picked from commit 539573c317dc0b8d50a128db60550f2f2898d2fc) +Signed-off-by: Laurent Vivier +--- + hw/net/vhost_net.c | 7 +++++++ + include/net/net.h | 2 ++ + 2 files changed, 9 insertions(+) + +diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c +index 9d4b334453..d28f8b974b 100644 +--- a/hw/net/vhost_net.c ++++ b/hw/net/vhost_net.c +@@ -281,6 +281,13 @@ static int vhost_net_start_one(struct vhost_net *net, + } + } + } ++ ++ if (net->nc->info->load) { ++ r = net->nc->info->load(net->nc); ++ if (r < 0) { ++ goto fail; ++ } ++ } + return 0; + fail: + file.fd = -1; +diff --git a/include/net/net.h b/include/net/net.h +index 476ad45b9a..81d0b21def 100644 +--- a/include/net/net.h ++++ b/include/net/net.h +@@ -45,6 +45,7 @@ typedef struct NICConf { + typedef void (NetPoll)(NetClientState *, bool enable); + typedef bool (NetCanReceive)(NetClientState *); + typedef int (NetStart)(NetClientState *); ++typedef int (NetLoad)(NetClientState *); + typedef void (NetStop)(NetClientState *); + typedef ssize_t (NetReceive)(NetClientState *, const uint8_t *, size_t); + typedef ssize_t (NetReceiveIOV)(NetClientState *, const struct iovec *, int); +@@ -74,6 +75,7 @@ typedef struct NetClientInfo { + NetReceiveIOV *receive_iov; + NetCanReceive *can_receive; + NetStart *start; ++ NetLoad *load; + NetStop *stop; + NetCleanup *cleanup; + LinkStatusChanged *link_status_changed; +-- +2.31.1 + diff --git a/kvm-virtio-net-Update-virtio-net-curr_queue_pairs-in-vdp.patch b/kvm-virtio-net-Update-virtio-net-curr_queue_pairs-in-vdp.patch new file mode 100644 index 0000000..7629017 --- /dev/null +++ b/kvm-virtio-net-Update-virtio-net-curr_queue_pairs-in-vdp.patch @@ -0,0 +1,61 @@ +From 9e23182c5249f876e56ef9a31b22476b5268f246 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Eugenio=20P=C3=A9rez?= +Date: Thu, 11 Aug 2022 16:40:07 +0200 +Subject: [PATCH 24/29] virtio-net: Update virtio-net curr_queue_pairs in vdpa + backends +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Laurent Vivier +RH-MergeRequest: 117: vDPA SVQ Multiqueue support +RH-Jira: RHELX-57 +RH-Acked-by: Jason Wang +RH-Acked-by: Cindy Lu +RH-Acked-by: Eugenio Pérez +RH-Commit: [24/25] e0e6978394d6496a7e12cf8424b2e9cb87281a90 (redhat/centos-stream/src/qemu-kvm) + +Upstream: Not merged yet + +It was returned as error before. Instead of it, simply update the +corresponding field so qemu can send it in the migration data. + +Signed-off-by: Eugenio Pérez +Signed-off-by: Laurent Vivier +--- + hw/net/virtio-net.c | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index dd0d056fde..63a8332cd0 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -1412,19 +1412,14 @@ static int virtio_net_handle_mq(VirtIONet *n, uint8_t cmd, + return VIRTIO_NET_ERR; + } + +- /* Avoid changing the number of queue_pairs for vdpa device in +- * userspace handler. A future fix is needed to handle the mq +- * change in userspace handler with vhost-vdpa. Let's disable +- * the mq handling from userspace for now and only allow get +- * done through the kernel. Ripples may be seen when falling +- * back to userspace, but without doing it qemu process would +- * crash on a recursive entry to virtio_net_set_status(). +- */ ++ n->curr_queue_pairs = queue_pairs; + if (nc->peer && nc->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) { +- return VIRTIO_NET_ERR; ++ /* ++ * Avoid updating the backend for a vdpa device: We're only interested ++ * in updating the device model queues. ++ */ ++ return VIRTIO_NET_OK; + } +- +- n->curr_queue_pairs = queue_pairs; + /* stop the backend before changing the number of queue_pairs to avoid handling a + * disabled queue */ + virtio_net_set_status(vdev, vdev->status); +-- +2.31.1 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index f8c08dd..138d06d 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -151,7 +151,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \ Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm Version: 7.1.0 -Release: 1%{?rcrel}%{?dist}%{?cc_suffix} +Release: 2%{?rcrel}%{?dist}%{?cc_suffix} # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped # Epoch 15 used for RHEL 8 # Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5) @@ -175,8 +175,6 @@ Source30: kvm-s390x.conf Source31: kvm-x86.conf Source36: README.tests -Source37: capstone.tar.gz - Patch0004: 0004-Initial-redhat-build.patch Patch0005: 0005-Re-enable-capstone-internal-build.patch @@ -193,6 +191,62 @@ Patch0015: 0015-Use-qemu-kvm-in-documentation-instead-of-qemu-system.patch Patch0016: 0016-BZ1653590-Require-at-least-64kiB-pages-for-downstrea.patch Patch0017: 0017-qcow2-Deprecation-warning-when-opening-v2-images-rw.patch Patch0018: 0018-Introduce-upstream-7.0-compat-changes.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch19: kvm-vdpa-Skip-the-maps-not-in-the-iova-tree.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch20: kvm-vdpa-do-not-save-failed-dma-maps-in-SVQ-iova-tree.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch21: kvm-util-accept-iova_tree_remove_parameter-by-value.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch22: kvm-vdpa-Remove-SVQ-vring-from-iova_tree-at-shutdown.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch23: kvm-vdpa-Make-SVQ-vring-unmapping-return-void.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch24: kvm-vhost-Always-store-new-kick-fd-on-vhost_svq_set_svq_.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch25: kvm-vdpa-Use-ring-hwaddr-at-vhost_vdpa_svq_unmap_ring.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch26: kvm-vhost-stop-transfer-elem-ownership-in-vhost_handle_g.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch27: kvm-vhost-use-SVQ-element-ndescs-instead-of-opaque-data-.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch28: kvm-vhost-Delete-useless-read-memory-barrier.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch29: kvm-vhost-Do-not-depend-on-NULL-VirtQueueElement-on-vhos.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch30: kvm-vhost_net-Add-NetClientInfo-start-callback.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch31: kvm-vhost_net-Add-NetClientInfo-stop-callback.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch32: kvm-vdpa-add-net_vhost_vdpa_cvq_info-NetClientInfo.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch33: kvm-vdpa-Move-command-buffers-map-to-start-of-net-device.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch34: kvm-vdpa-extract-vhost_vdpa_net_cvq_add-from-vhost_vdpa_.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch35: kvm-vhost_net-add-NetClientState-load-callback.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch36: kvm-vdpa-Add-virtio-net-mac-address-via-CVQ-at-start.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch37: kvm-vdpa-Delete-CVQ-migration-blocker.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch38: kvm-vdpa-Make-VhostVDPAState-cvq_cmd_in_buffer-control-a.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch39: kvm-vdpa-extract-vhost_vdpa_net_load_mac-from-vhost_vdpa.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch40: kvm-vdpa-Add-vhost_vdpa_net_load_mq.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch41: kvm-vdpa-validate-MQ-CVQ-commands.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch42: kvm-virtio-net-Update-virtio-net-curr_queue_pairs-in-vdp.patch +# For RHELX-57 - vDPA SVQ Multiqueue support +Patch43: kvm-vdpa-Allow-MQ-feature-in-SVQ.patch +# For bz#2125281 - [RHEL9.1] Guests in VMX root operation fail to reboot with QEMU's 'system_reset' command [rhel-9.2.0] +Patch44: kvm-i386-reset-KVM-nested-state-upon-CPU-reset.patch +# For bz#2125281 - [RHEL9.1] Guests in VMX root operation fail to reboot with QEMU's 'system_reset' command [rhel-9.2.0] +Patch45: kvm-i386-do-kvm_put_msr_feature_control-first-thing-when.patch +# For bz#2127825 - Use capstone for qemu-kvm build +Patch46: kvm-Revert-Re-enable-capstone-internal-build.patch %if %{have_clang} BuildRequires: clang @@ -263,6 +317,7 @@ BuildRequires: perl-Test-Harness BuildRequires: libslirp-devel BuildRequires: pulseaudio-libs-devel BuildRequires: spice-protocol +BuildRequires: capstone-devel # Requires for qemu-kvm package Requires: %{name}-core = %{epoch}:%{version}-%{release} @@ -290,6 +345,7 @@ Requires: edk2-ovmf %ifarch aarch64 Requires: edk2-aarch64 %endif +Requires: capstone Requires: libseccomp >= %{libseccomp_version} Requires: libusbx >= %{libusbx_version} @@ -504,7 +560,6 @@ This package provides usbredir support. %prep %setup -q -n qemu-%{version}%{?rcstr} %autopatch -p1 -/usr/bin/gzip -dc %{SOURCE37} | /usr/bin/tar -xof - %global qemu_kvm_build qemu_kvm_build mkdir -p %{qemu_kvm_build} @@ -691,7 +746,7 @@ run_configure \ %endif --enable-attr \ --enable-cap-ng \ - --enable-capstone=internal \ + --enable-capstone \ --enable-coroutine-pool \ --enable-curl \ --enable-debug-info \ @@ -1224,6 +1279,43 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Thu Sep 29 2022 Miroslav Rezanina - 7.1.0-2 +- kvm-vdpa-Skip-the-maps-not-in-the-iova-tree.patch [RHELX-57] +- kvm-vdpa-do-not-save-failed-dma-maps-in-SVQ-iova-tree.patch [RHELX-57] +- kvm-util-accept-iova_tree_remove_parameter-by-value.patch [RHELX-57] +- kvm-vdpa-Remove-SVQ-vring-from-iova_tree-at-shutdown.patch [RHELX-57] +- kvm-vdpa-Make-SVQ-vring-unmapping-return-void.patch [RHELX-57] +- kvm-vhost-Always-store-new-kick-fd-on-vhost_svq_set_svq_.patch [RHELX-57] +- kvm-vdpa-Use-ring-hwaddr-at-vhost_vdpa_svq_unmap_ring.patch [RHELX-57] +- kvm-vhost-stop-transfer-elem-ownership-in-vhost_handle_g.patch [RHELX-57] +- kvm-vhost-use-SVQ-element-ndescs-instead-of-opaque-data-.patch [RHELX-57] +- kvm-vhost-Delete-useless-read-memory-barrier.patch [RHELX-57] +- kvm-vhost-Do-not-depend-on-NULL-VirtQueueElement-on-vhos.patch [RHELX-57] +- kvm-vhost_net-Add-NetClientInfo-start-callback.patch [RHELX-57] +- kvm-vhost_net-Add-NetClientInfo-stop-callback.patch [RHELX-57] +- kvm-vdpa-add-net_vhost_vdpa_cvq_info-NetClientInfo.patch [RHELX-57] +- kvm-vdpa-Move-command-buffers-map-to-start-of-net-device.patch [RHELX-57] +- kvm-vdpa-extract-vhost_vdpa_net_cvq_add-from-vhost_vdpa_.patch [RHELX-57] +- kvm-vhost_net-add-NetClientState-load-callback.patch [RHELX-57] +- kvm-vdpa-Add-virtio-net-mac-address-via-CVQ-at-start.patch [RHELX-57] +- kvm-vdpa-Delete-CVQ-migration-blocker.patch [RHELX-57] +- kvm-vdpa-Make-VhostVDPAState-cvq_cmd_in_buffer-control-a.patch [RHELX-57] +- kvm-vdpa-extract-vhost_vdpa_net_load_mac-from-vhost_vdpa.patch [RHELX-57] +- kvm-vdpa-Add-vhost_vdpa_net_load_mq.patch [RHELX-57] +- kvm-vdpa-validate-MQ-CVQ-commands.patch [RHELX-57] +- kvm-virtio-net-Update-virtio-net-curr_queue_pairs-in-vdp.patch [RHELX-57] +- kvm-vdpa-Allow-MQ-feature-in-SVQ.patch [RHELX-57] +- kvm-i386-reset-KVM-nested-state-upon-CPU-reset.patch [bz#2125281] +- kvm-i386-do-kvm_put_msr_feature_control-first-thing-when.patch [bz#2125281] +- kvm-Revert-Re-enable-capstone-internal-build.patch [bz#2127825] +- kvm-spec-Use-capstone-package.patch [bz#2127825] +- Resolves: RHELX-57 + (vDPA SVQ Multiqueue support ) +- Resolves: bz#2125281 + ([RHEL9.1] Guests in VMX root operation fail to reboot with QEMU's 'system_reset' command [rhel-9.2.0]) +- Resolves: bz#2127825 + (Use capstone for qemu-kvm build) + * Mon Sep 05 2022 Miroslav Rezanina - 7.1.0-1 - Rebase to QEMU 7.1.0 [bz#2111769] - Resolves: bz#2111769 diff --git a/sources b/sources index 5506976..9b00967 100644 --- a/sources +++ b/sources @@ -1,2 +1 @@ -SHA512 (capstone.tar.gz) = 14c5a3f3807c9294258de5bf294563fcdb56b50630cf3080dc681ae1415d938dce9485d7b0fef61cfb4a2381696f0e74c7da149b2b6218cdbb00521cd365c7e4 SHA512 (qemu-7.1.0.tar.xz) = c60c5ff8ec99b7552e485768908920658fdd8035ff7a6fa370fb6881957dc8b7e5f18ff1a8f49bd6aa22909ede2a7c084986d8244f12074ccd33ebe40a0c411f