From 9cc71e44f4a635d3bb1ddfc347088df7bb3298ab2300ff465b765a78476693d5 Mon Sep 17 00:00:00 2001 From: Li Zhang Date: Fri, 8 Oct 2021 16:10:31 +0000 Subject: [PATCH] Accepting request 924265 from home:lizhang:branches:Virtualization - Stable fixes from upstream * Patches added: block-introduce-max_hw_iov-for-use-in-sc.patch hmp-Unbreak-change-vnc.patch qemu-nbd-Change-default-cache-mode-to-wr.patch target-arm-Don-t-skip-M-profile-reset-en.patch vhost-vsock-fix-migration-issue-when-seq.patch virtio-mem-pci-Fix-memory-leak-when-crea.patch virtio-net-fix-use-after-unmap-free-for-.patch OBS-URL: https://build.opensuse.org/request/show/924265 OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=675 --- ...k-introduce-max_hw_iov-for-use-in-sc.patch | 123 ++++++++++++++++++ bundles.tar.xz | 4 +- hmp-Unbreak-change-vnc.patch | 59 +++++++++ ...-nbd-Change-default-cache-mode-to-wr.patch | 112 ++++++++++++++++ qemu.changes | 13 ++ qemu.spec | 14 ++ ...et-arm-Don-t-skip-M-profile-reset-en.patch | 88 +++++++++++++ ...t-vsock-fix-migration-issue-when-seq.patch | 101 ++++++++++++++ ...io-mem-pci-Fix-memory-leak-when-crea.patch | 39 ++++++ ...io-net-fix-use-after-unmap-free-for-.patch | 121 +++++++++++++++++ 10 files changed, 672 insertions(+), 2 deletions(-) create mode 100644 block-introduce-max_hw_iov-for-use-in-sc.patch create mode 100644 hmp-Unbreak-change-vnc.patch create mode 100644 qemu-nbd-Change-default-cache-mode-to-wr.patch create mode 100644 target-arm-Don-t-skip-M-profile-reset-en.patch create mode 100644 vhost-vsock-fix-migration-issue-when-seq.patch create mode 100644 virtio-mem-pci-Fix-memory-leak-when-crea.patch create mode 100644 virtio-net-fix-use-after-unmap-free-for-.patch diff --git a/block-introduce-max_hw_iov-for-use-in-sc.patch b/block-introduce-max_hw_iov-for-use-in-sc.patch new file mode 100644 index 00000000..bf17e096 --- /dev/null +++ b/block-introduce-max_hw_iov-for-use-in-sc.patch @@ -0,0 +1,123 @@ +From: Paolo Bonzini +Date: Thu, 23 Sep 2021 09:04:36 -0400 +Subject: block: introduce max_hw_iov for use in scsi-generic + +Git-commit: cc071629539dc1f303175a7e2d4ab854c0a8b20f + +Linux limits the size of iovecs to 1024 (UIO_MAXIOV in the kernel +sources, IOV_MAX in POSIX). Because of this, on some host adapters +requests with many iovecs are rejected with -EINVAL by the +io_submit() or readv()/writev() system calls. + +In fact, the same limit applies to SG_IO as well. To fix both the +EINVAL and the possible performance issues from using fewer iovecs +than allowed by Linux (some HBAs have max_segments as low as 128), +introduce a separate entry in BlockLimits to hold the max_segments +value from sysfs. This new limit is used only for SG_IO and clamped +to bs->bl.max_iov anyway, just like max_hw_transfer is clamped to +bs->bl.max_transfer. + +Reported-by: Halil Pasic +Cc: Hanna Reitz +Cc: Kevin Wolf +Cc: qemu-block@nongnu.org +Cc: qemu-stable@nongnu.org +Fixes: 18473467d5 ("file-posix: try BLKSECTGET on block devices too, do not round to power of 2", 2021-06-25) +Signed-off-by: Paolo Bonzini +Message-Id: <20210923130436.1187591-1-pbonzini@redhat.com> +Signed-off-by: Kevin Wolf +Signed-off-by: Li Zhang +--- + block/block-backend.c | 6 ++++++ + block/file-posix.c | 2 +- + block/io.c | 1 + + hw/scsi/scsi-generic.c | 2 +- + include/block/block_int.h | 7 +++++++ + include/sysemu/block-backend.h | 1 + + 6 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/block/block-backend.c b/block/block-backend.c +index deb55c272ead88648c9c66ebf2e4..6320752aa2a104503300d69a4f03 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -1978,6 +1978,12 @@ uint32_t blk_get_max_transfer(BlockBackend *blk) + return ROUND_DOWN(max, blk_get_request_alignment(blk)); + } + ++int blk_get_max_hw_iov(BlockBackend *blk) ++{ ++ return MIN_NON_ZERO(blk->root->bs->bl.max_hw_iov, ++ blk->root->bs->bl.max_iov); ++} ++ + int blk_get_max_iov(BlockBackend *blk) + { + return blk->root->bs->bl.max_iov; +diff --git a/block/file-posix.c b/block/file-posix.c +index cb9bffe0471c39e85146780b4a77..1567edb3d5cb4e85af27dc390843 100644 +--- a/block/file-posix.c ++++ b/block/file-posix.c +@@ -1273,7 +1273,7 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp) + + ret = hdev_get_max_segments(s->fd, &st); + if (ret > 0) { +- bs->bl.max_iov = ret; ++ bs->bl.max_hw_iov = ret; + } + } + } +diff --git a/block/io.c b/block/io.c +index a19942718b5d00cb1e54bc9e8228..f38e7f81d8e4c4a3fdf9a47496ab 100644 +--- a/block/io.c ++++ b/block/io.c +@@ -136,6 +136,7 @@ static void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src) + dst->min_mem_alignment = MAX(dst->min_mem_alignment, + src->min_mem_alignment); + dst->max_iov = MIN_NON_ZERO(dst->max_iov, src->max_iov); ++ dst->max_hw_iov = MIN_NON_ZERO(dst->max_hw_iov, src->max_hw_iov); + } + + typedef struct BdrvRefreshLimitsState { +diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c +index 665baf900e45883d462430db8475..0306ccc7b1e4827a67aaed926f93 100644 +--- a/hw/scsi/scsi-generic.c ++++ b/hw/scsi/scsi-generic.c +@@ -180,7 +180,7 @@ static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len) + page = r->req.cmd.buf[2]; + if (page == 0xb0) { + uint64_t max_transfer = blk_get_max_hw_transfer(s->conf.blk); +- uint32_t max_iov = blk_get_max_iov(s->conf.blk); ++ uint32_t max_iov = blk_get_max_hw_iov(s->conf.blk); + + assert(max_transfer); + max_transfer = MIN_NON_ZERO(max_transfer, max_iov * qemu_real_host_page_size) +diff --git a/include/block/block_int.h b/include/block/block_int.h +index f1a54db0f8ce693399d0352f69ce..c31cbd034a1b5a427c876709ac66 100644 +--- a/include/block/block_int.h ++++ b/include/block/block_int.h +@@ -702,6 +702,13 @@ typedef struct BlockLimits { + */ + uint64_t max_hw_transfer; + ++ /* Maximal number of scatter/gather elements allowed by the hardware. ++ * Applies whenever transfers to the device bypass the kernel I/O ++ * scheduler, for example with SG_IO. If larger than max_iov ++ * or if zero, blk_get_max_hw_iov will fall back to max_iov. ++ */ ++ int max_hw_iov; ++ + /* memory alignment, in bytes so that no bounce buffer is needed */ + size_t min_mem_alignment; + +diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h +index 9ac5f7bbd3a17d87d8a59abb3a65..5daec61f6ecce87e94825cff01af 100644 +--- a/include/sysemu/block-backend.h ++++ b/include/sysemu/block-backend.h +@@ -210,6 +210,7 @@ uint32_t blk_get_request_alignment(BlockBackend *blk); + uint32_t blk_get_max_transfer(BlockBackend *blk); + uint64_t blk_get_max_hw_transfer(BlockBackend *blk); + int blk_get_max_iov(BlockBackend *blk); ++int blk_get_max_hw_iov(BlockBackend *blk); + void blk_set_guest_block_size(BlockBackend *blk, int align); + void *blk_try_blockalign(BlockBackend *blk, size_t size); + void *blk_blockalign(BlockBackend *blk, size_t size); diff --git a/bundles.tar.xz b/bundles.tar.xz index 5826df0f..f4d06aaa 100644 --- a/bundles.tar.xz +++ b/bundles.tar.xz @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:75b23e881e084f164f0e4cc474a7141d1a6ec4a3b5a3494ffc5f5e61d516f8a5 -size 45100 +oid sha256:898b254c29675506ea3a140a2188cd9036adc5f4d9e9c7997de7852c2408870b +size 58180 diff --git a/hmp-Unbreak-change-vnc.patch b/hmp-Unbreak-change-vnc.patch new file mode 100644 index 00000000..b15e59fb --- /dev/null +++ b/hmp-Unbreak-change-vnc.patch @@ -0,0 +1,59 @@ +From: Markus Armbruster +Date: Thu, 9 Sep 2021 10:12:18 +0200 +Subject: hmp: Unbreak "change vnc" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Git-commit: 6193344f9337f8b76cd44ce94a32c9900d907d35 + +HMP command "change vnc" can take the password as argument, or prompt +for it: + + (qemu) change vnc password 123 + (qemu) change vnc password + Password: *** + (qemu) + +This regressed in commit cfb5387a1d "hmp: remove "change vnc TARGET" +command", v6.0.0. + + (qemu) change vnc passwd 123 + Password: *** + (qemu) change vnc passwd + (qemu) + +The latter passes NULL to qmp_change_vnc_password(), which is a no-no. +Looks like it puts the display into "password required, but none set" +state. + +The logic error is easy to miss in review, but testing should've +caught it. + +Fix the obvious way. + +Fixes: cfb5387a1de2acda23fb5c97d2378b9e7ddf8025 +Cc: qemu-stable@nongnu.org +Signed-off-by: Markus Armbruster +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Gerd Hoffmann +Message-Id: <20210909081219.308065-2-armbru@redhat.com> +Signed-off-by: Laurent Vivier +Signed-off-by: Li Zhang +--- + monitor/hmp-cmds.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c +index e00255f7ee707c9a430268183a6b..a7e197a90bf7f5ad8c71140c6d55 100644 +--- a/monitor/hmp-cmds.c ++++ b/monitor/hmp-cmds.c +@@ -1496,7 +1496,7 @@ void hmp_change(Monitor *mon, const QDict *qdict) + } + if (strcmp(target, "passwd") == 0 || + strcmp(target, "password") == 0) { +- if (arg) { ++ if (!arg) { + MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common); + monitor_read_password(hmp_mon, hmp_change_read_arg, NULL); + return; diff --git a/qemu-nbd-Change-default-cache-mode-to-wr.patch b/qemu-nbd-Change-default-cache-mode-to-wr.patch new file mode 100644 index 00000000..425f9d35 --- /dev/null +++ b/qemu-nbd-Change-default-cache-mode-to-wr.patch @@ -0,0 +1,112 @@ +From: Nir Soffer +Date: Fri, 13 Aug 2021 23:55:19 +0300 +Subject: qemu-nbd: Change default cache mode to writeback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Git-commit: 09615257058a0ae87b837bb041f56f7312d9ead8 + +Both qemu and qemu-img use writeback cache mode by default, which is +already documented in qemu(1). qemu-nbd uses writethrough cache mode by +default, and the default cache mode is not documented. + +According to the qemu-nbd(8): + + --cache=CACHE + The cache mode to be used with the file. See the + documentation of the emulator's -drive cache=... option for + allowed values. + +qemu(1) says: + + The default mode is cache=writeback. + +So users have no reason to assume that qemu-nbd is using writethough +cache mode. The only hint is the painfully slow writing when using the +defaults. + +Looking in git history, it seems that qemu used writethrough in the past +to support broken guests that did not flush data properly, or could not +flush due to limitations in qemu. But qemu-nbd clients can use +NBD_CMD_FLUSH to flush data, so using writethrough does not help anyone. + +Change the default cache mode to writback, and document the default and +available values properly in the online help and manual. + +With this change converting image via qemu-nbd is 3.5 times faster. + + $ qemu-img create dst.img 50g + $ qemu-nbd -t -f raw -k /tmp/nbd.sock dst.img + +Before this change: + + $ hyperfine -r3 "./qemu-img convert -p -f raw -O raw -T none -W fedora34.img nbd+unix:///?socket=/tmp/nbd.sock" + Benchmark #1: ./qemu-img convert -p -f raw -O raw -T none -W fedora34.img nbd+unix:///?socket=/tmp/nbd.sock + Time (mean ± σ): 83.639 s ± 5.970 s [User: 2.733 s, System: 6.112 s] + Range (min … max): 76.749 s … 87.245 s 3 runs + +After this change: + + $ hyperfine -r3 "./qemu-img convert -p -f raw -O raw -T none -W fedora34.img nbd+unix:///?socket=/tmp/nbd.sock" + Benchmark #1: ./qemu-img convert -p -f raw -O raw -T none -W fedora34.img nbd+unix:///?socket=/tmp/nbd.sock + Time (mean ± σ): 23.522 s ± 0.433 s [User: 2.083 s, System: 5.475 s] + Range (min … max): 23.234 s … 24.019 s 3 runs + +Users can avoid the issue by using --cache=writeback[1] but the defaults +should give good performance for the common use case. + +[1] https://bugzilla.redhat.com/1990656 + +Signed-off-by: Nir Soffer +Message-Id: <20210813205519.50518-1-nsoffer@redhat.com> +Reviewed-by: Eric Blake +CC: qemu-stable@nongnu.org +Signed-off-by: Eric Blake +Signed-off-by: Li Zhang +--- + docs/tools/qemu-nbd.rst | 6 ++++-- + qemu-nbd.c | 6 ++++-- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/docs/tools/qemu-nbd.rst b/docs/tools/qemu-nbd.rst +index ee862fa0bc02667bb67f99447b23..5643da26e98241c1fa0969b90b2c 100644 +--- a/docs/tools/qemu-nbd.rst ++++ b/docs/tools/qemu-nbd.rst +@@ -98,8 +98,10 @@ driver options if ``--image-opts`` is specified. + + .. option:: --cache=CACHE + +- The cache mode to be used with the file. See the documentation of +- the emulator's ``-drive cache=...`` option for allowed values. ++ The cache mode to be used with the file. Valid values are: ++ ``none``, ``writeback`` (the default), ``writethrough``, ++ ``directsync`` and ``unsafe``. See the documentation of ++ the emulator's ``-drive cache=...`` option for more info. + + .. option:: -n, --nocache + +diff --git a/qemu-nbd.c b/qemu-nbd.c +index 26ffbf15af0a755dddc99e27c876..6c18fcd19a07b7194a5c2defdc73 100644 +--- a/qemu-nbd.c ++++ b/qemu-nbd.c +@@ -135,7 +135,9 @@ static void usage(const char *name) + " 'snapshot.id=[ID],snapshot.name=[NAME]', or\n" + " '[ID_OR_NAME]'\n" + " -n, --nocache disable host cache\n" +-" --cache=MODE set cache mode (none, writeback, ...)\n" ++" --cache=MODE set cache mode used to access the disk image, the\n" ++" valid options are: 'none', 'writeback' (default),\n" ++" 'writethrough', 'directsync' and 'unsafe'\n" + " --aio=MODE set AIO mode (native, io_uring or threads)\n" + " --discard=MODE set discard mode (ignore, unmap)\n" + " --detect-zeroes=MODE set detect-zeroes mode (off, on, unmap)\n" +@@ -552,7 +554,7 @@ int main(int argc, char **argv) + bool alloc_depth = false; + const char *tlscredsid = NULL; + bool imageOpts = false; +- bool writethrough = true; ++ bool writethrough = false; /* Client will flush as needed. */ + bool fork_process = false; + bool list = false; + int old_stderr = -1; diff --git a/qemu.changes b/qemu.changes index e420eec3..7631a8a2 100644 --- a/qemu.changes +++ b/qemu.changes @@ -1,3 +1,16 @@ +------------------------------------------------------------------- +Fri Oct 8 13:48:40 UTC 2021 - Li Zhang + +- Stable fixes from upstream +* Patches added: + block-introduce-max_hw_iov-for-use-in-sc.patch + hmp-Unbreak-change-vnc.patch + qemu-nbd-Change-default-cache-mode-to-wr.patch + target-arm-Don-t-skip-M-profile-reset-en.patch + vhost-vsock-fix-migration-issue-when-seq.patch + virtio-mem-pci-Fix-memory-leak-when-crea.patch + virtio-net-fix-use-after-unmap-free-for-.patch + ------------------------------------------------------------------- Thu Sep 16 03:55:52 UTC 2021 - José Ricardo Ziviani diff --git a/qemu.spec b/qemu.spec index d1b36bd5..6a5b667f 100644 --- a/qemu.spec +++ b/qemu.spec @@ -188,6 +188,13 @@ Patch00052: qemu-sockets-fix-unix-socket-path-copy-a.patch Patch00053: target-i386-add-missing-bits-to-CR4_RESE.patch Patch00054: qemu-binfmt-conf.sh-should-use-F-as-shor.patch Patch00055: modules-quick-fix-a-fundamental-error-in.patch +Patch00056: virtio-net-fix-use-after-unmap-free-for-.patch +Patch00057: target-arm-Don-t-skip-M-profile-reset-en.patch +Patch00058: hmp-Unbreak-change-vnc.patch +Patch00059: qemu-nbd-Change-default-cache-mode-to-wr.patch +Patch00060: virtio-mem-pci-Fix-memory-leak-when-crea.patch +Patch00061: vhost-vsock-fix-migration-issue-when-seq.patch +Patch00062: block-introduce-max_hw_iov-for-use-in-sc.patch # Patches applied in roms/seabios/: Patch01000: seabios-use-python2-explicitly-as-needed.patch Patch01001: seabios-switch-to-python3-as-needed.patch @@ -1134,6 +1141,13 @@ This package records qemu testsuite results and represents successful testing. %patch00053 -p1 %patch00054 -p1 %patch00055 -p1 +%patch00056 -p1 +%patch00057 -p1 +%patch00058 -p1 +%patch00059 -p1 +%patch00060 -p1 +%patch00061 -p1 +%patch00062 -p1 %patch01000 -p1 %patch01001 -p1 %patch01002 -p1 diff --git a/target-arm-Don-t-skip-M-profile-reset-en.patch b/target-arm-Don-t-skip-M-profile-reset-en.patch new file mode 100644 index 00000000..85c3fc77 --- /dev/null +++ b/target-arm-Don-t-skip-M-profile-reset-en.patch @@ -0,0 +1,88 @@ +From: Peter Maydell +Date: Mon, 20 Sep 2021 09:54:33 +0100 +Subject: target/arm: Don't skip M-profile reset entirely in user mode + +Git-commit: b62ceeaf8096fdbbbfdc6087da0028bc4a4dd77e + +Currently all of the M-profile specific code in arm_cpu_reset() is +inside a !defined(CONFIG_USER_ONLY) ifdef block. This is +unintentional: it happened because originally the only +M-profile-specific handling was the setup of the initial SP and PC +from the vector table, which is system-emulation only. But then we +added a lot of other M-profile setup to the same "if (ARM_FEATURE_M)" +code block without noticing that it was all inside a not-user-mode +ifdef. This has generally been harmless, but with the addition of +v8.1M low-overhead-loop support we ran into a problem: the reset of +FPSCR.LTPSIZE to 4 was only being done for system emulation mode, so +if a user-mode guest tried to execute the LE instruction it would +incorrectly take a UsageFault. + +Adjust the ifdefs so only the really system-emulation specific parts +are covered. Because this means we now run some reset code that sets +up initial values in the FPCCR and similar FPU related registers, +explicitly set up the registers controlling FPU context handling in +user-emulation mode so that the FPU works by design and not by +chance. + +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/613 +Cc: qemu-stable@nongnu.org +Signed-off-by: Peter Maydell +Reviewed-by: Richard Henderson +Message-id: 20210914120725.24992-2-peter.maydell@linaro.org +Signed-off-by: Li Zhang +--- + target/arm/cpu.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/target/arm/cpu.c b/target/arm/cpu.c +index 2866dd765882c87eb773493d04cd..af60c07ca1421558cae5cc2e3128 100644 +--- a/target/arm/cpu.c ++++ b/target/arm/cpu.c +@@ -265,12 +265,15 @@ static void arm_cpu_reset(DeviceState *dev) + env->uncached_cpsr = ARM_CPU_MODE_SVC; + } + env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F; ++#endif + + if (arm_feature(env, ARM_FEATURE_M)) { ++#ifndef CONFIG_USER_ONLY + uint32_t initial_msp; /* Loaded from 0x0 */ + uint32_t initial_pc; /* Loaded from 0x4 */ + uint8_t *rom; + uint32_t vecbase; ++#endif + + if (cpu_isar_feature(aa32_lob, cpu)) { + /* +@@ -324,6 +327,8 @@ static void arm_cpu_reset(DeviceState *dev) + env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK | + R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK; + } ++ ++#ifndef CONFIG_USER_ONLY + /* Unlike A/R profile, M profile defines the reset LR value */ + env->regs[14] = 0xffffffff; + +@@ -352,8 +357,22 @@ static void arm_cpu_reset(DeviceState *dev) + env->regs[13] = initial_msp & 0xFFFFFFFC; + env->regs[15] = initial_pc & ~1; + env->thumb = initial_pc & 1; ++#else ++ /* ++ * For user mode we run non-secure and with access to the FPU. ++ * The FPU context is active (ie does not need further setup) ++ * and is owned by non-secure. ++ */ ++ env->v7m.secure = false; ++ env->v7m.nsacr = 0xcff; ++ env->v7m.cpacr[M_REG_NS] = 0xf0ffff; ++ env->v7m.fpccr[M_REG_S] &= ++ ~(R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK); ++ env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK; ++#endif + } + ++#ifndef CONFIG_USER_ONLY + /* AArch32 has a hard highvec setting of 0xFFFF0000. If we are currently + * executing as AArch32 then check if highvecs are enabled and + * adjust the PC accordingly. diff --git a/vhost-vsock-fix-migration-issue-when-seq.patch b/vhost-vsock-fix-migration-issue-when-seq.patch new file mode 100644 index 00000000..9a3320ff --- /dev/null +++ b/vhost-vsock-fix-migration-issue-when-seq.patch @@ -0,0 +1,101 @@ +From: Stefano Garzarella +Date: Tue, 21 Sep 2021 18:16:41 +0200 +Subject: vhost-vsock: fix migration issue when seqpacket is supported + +Git-commit: d6a9378f47515c6d70dbff4912c5740c98709880 + +Commit 1e08fd0a46 ("vhost-vsock: SOCK_SEQPACKET feature bit support") +enabled the SEQPACKET feature bit. +This commit is released with QEMU 6.1, so if we try to migrate a VM where +the host kernel supports SEQPACKET but machine type version is less than +6.1, we get the following errors: + + Features 0x130000002 unsupported. Allowed features: 0x179000000 + Failed to load virtio-vhost_vsock:virtio + error while loading state for instance 0x0 of device '0000:00:05.0/virtio-vhost_vsock' + load of migration failed: Operation not permitted + +Let's disable the feature bit for machine types < 6.1. +We add a new OnOffAuto property for this, called `seqpacket`. +When it is `auto` (default), QEMU behaves as before, trying to enable the +feature, when it is `on` QEMU will fail if the backend (vhost-vsock +kernel module) doesn't support it. + +Fixes: 1e08fd0a46 ("vhost-vsock: SOCK_SEQPACKET feature bit support") +Cc: qemu-stable@nongnu.org +Reported-by: Jiang Wang +Signed-off-by: Stefano Garzarella +Message-Id: <20210921161642.206461-2-sgarzare@redhat.com> +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Li Zhang +--- + hw/core/machine.c | 1 + + hw/virtio/vhost-vsock.c | 19 ++++++++++++++++--- + include/hw/virtio/vhost-vsock.h | 3 +++ + 3 files changed, 20 insertions(+), 3 deletions(-) + +diff --git a/hw/core/machine.c b/hw/core/machine.c +index 54e040587dd3526488d1688df535..2cf2f321f9bd50aa3f56e7af08ff 100644 +--- a/hw/core/machine.c ++++ b/hw/core/machine.c +@@ -43,6 +43,7 @@ GlobalProperty hw_compat_6_0[] = { + { "nvme-ns", "eui64-default", "off"}, + { "e1000", "init-vet", "off" }, + { "e1000e", "init-vet", "off" }, ++ { "vhost-vsock-device", "seqpacket", "off" }, + }; + const size_t hw_compat_6_0_len = G_N_ELEMENTS(hw_compat_6_0); + +diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c +index 1b1a5c70eded006acf3cd142b6e6..dade0da03147705ede0180dc3039 100644 +--- a/hw/virtio/vhost-vsock.c ++++ b/hw/virtio/vhost-vsock.c +@@ -114,10 +114,21 @@ static uint64_t vhost_vsock_get_features(VirtIODevice *vdev, + Error **errp) + { + VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); ++ VHostVSock *vsock = VHOST_VSOCK(vdev); ++ ++ if (vsock->seqpacket != ON_OFF_AUTO_OFF) { ++ virtio_add_feature(&requested_features, VIRTIO_VSOCK_F_SEQPACKET); ++ } ++ ++ requested_features = vhost_get_features(&vvc->vhost_dev, feature_bits, ++ requested_features); ++ ++ if (vsock->seqpacket == ON_OFF_AUTO_ON && ++ !virtio_has_feature(requested_features, VIRTIO_VSOCK_F_SEQPACKET)) { ++ error_setg(errp, "vhost-vsock backend doesn't support seqpacket"); ++ } + +- virtio_add_feature(&requested_features, VIRTIO_VSOCK_F_SEQPACKET); +- return vhost_get_features(&vvc->vhost_dev, feature_bits, +- requested_features); ++ return requested_features; + } + + static const VMStateDescription vmstate_virtio_vhost_vsock = { +@@ -218,6 +229,8 @@ static void vhost_vsock_device_unrealize(DeviceState *dev) + static Property vhost_vsock_properties[] = { + DEFINE_PROP_UINT64("guest-cid", VHostVSock, conf.guest_cid, 0), + DEFINE_PROP_STRING("vhostfd", VHostVSock, conf.vhostfd), ++ DEFINE_PROP_ON_OFF_AUTO("seqpacket", VHostVSock, seqpacket, ++ ON_OFF_AUTO_AUTO), + DEFINE_PROP_END_OF_LIST(), + }; + +diff --git a/include/hw/virtio/vhost-vsock.h b/include/hw/virtio/vhost-vsock.h +index 84f4e727c70fa7a00b68487e22f2..3f121a624f21796947dd1fbe3ed4 100644 +--- a/include/hw/virtio/vhost-vsock.h ++++ b/include/hw/virtio/vhost-vsock.h +@@ -30,6 +30,9 @@ struct VHostVSock { + VHostVSockCommon parent; + VHostVSockConf conf; + ++ /* features */ ++ OnOffAuto seqpacket; ++ + /*< public >*/ + }; + diff --git a/virtio-mem-pci-Fix-memory-leak-when-crea.patch b/virtio-mem-pci-Fix-memory-leak-when-crea.patch new file mode 100644 index 00000000..744b7160 --- /dev/null +++ b/virtio-mem-pci-Fix-memory-leak-when-crea.patch @@ -0,0 +1,39 @@ +From: David Hildenbrand +Date: Wed, 29 Sep 2021 18:24:43 +0200 +Subject: virtio-mem-pci: Fix memory leak when creating + MEMORY_DEVICE_SIZE_CHANGE event + +Git-commit: 75b98cb9f6456ccf194211beffcbf93b0a995fa4 + +Apparently, we don't have to duplicate the string. + +Fixes: 722a3c783ef4 ("virtio-pci: Send qapi events when the virtio-mem size changes") +Cc: qemu-stable@nongnu.org +Signed-off-by: David Hildenbrand +Reviewed-by: Markus Armbruster +Message-Id: <20210929162445.64060-2-david@redhat.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Li Zhang +--- + hw/virtio/virtio-mem-pci.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/hw/virtio/virtio-mem-pci.c b/hw/virtio/virtio-mem-pci.c +index fa5395cd88577964fba445c68f2d..7e384b7397edf9014c4e81df4ff5 100644 +--- a/hw/virtio/virtio-mem-pci.c ++++ b/hw/virtio/virtio-mem-pci.c +@@ -88,13 +88,8 @@ static void virtio_mem_pci_size_change_notify(Notifier *notifier, void *data) + size_change_notifier); + DeviceState *dev = DEVICE(pci_mem); + const uint64_t * const size_p = data; +- const char *id = NULL; + +- if (dev->id) { +- id = g_strdup(dev->id); +- } +- +- qapi_event_send_memory_device_size_change(!!id, id, *size_p); ++ qapi_event_send_memory_device_size_change(!!dev->id, dev->id, *size_p); + } + + static void virtio_mem_pci_class_init(ObjectClass *klass, void *data) diff --git a/virtio-net-fix-use-after-unmap-free-for-.patch b/virtio-net-fix-use-after-unmap-free-for-.patch new file mode 100644 index 00000000..ce8fb00e --- /dev/null +++ b/virtio-net-fix-use-after-unmap-free-for-.patch @@ -0,0 +1,121 @@ +From: Jason Wang +Date: Thu, 2 Sep 2021 13:44:12 +0800 +Subject: virtio-net: fix use after unmap/free for sg + +Git-commit: bedd7e93d01961fcb16a97ae45d93acf357e11f6 + +When mergeable buffer is enabled, we try to set the num_buffers after +the virtqueue elem has been unmapped. This will lead several issues, +E.g a use after free when the descriptor has an address which belongs +to the non direct access region. In this case we use bounce buffer +that is allocated during address_space_map() and freed during +address_space_unmap(). + +Fixing this by storing the elems temporarily in an array and delay the +unmap after we set the the num_buffers. + +This addresses CVE-2021-3748. + +Reported-by: Alexander Bulekov +Fixes: fbe78f4f55c6 ("virtio-net support") +Cc: qemu-stable@nongnu.org +Signed-off-by: Jason Wang +Signed-off-by: Li Zhang +--- + hw/net/virtio-net.c | 39 ++++++++++++++++++++++++++++++++------- + 1 file changed, 32 insertions(+), 7 deletions(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index 16d20cdee52ad6fbf1fdb4501483..f205331dcf8c31d4a350f68bdd71 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -1746,10 +1746,13 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, + VirtIONet *n = qemu_get_nic_opaque(nc); + VirtIONetQueue *q = virtio_net_get_subqueue(nc); + VirtIODevice *vdev = VIRTIO_DEVICE(n); ++ VirtQueueElement *elems[VIRTQUEUE_MAX_SIZE]; ++ size_t lens[VIRTQUEUE_MAX_SIZE]; + struct iovec mhdr_sg[VIRTQUEUE_MAX_SIZE]; + struct virtio_net_hdr_mrg_rxbuf mhdr; + unsigned mhdr_cnt = 0; +- size_t offset, i, guest_offset; ++ size_t offset, i, guest_offset, j; ++ ssize_t err; + + if (!virtio_net_can_receive(nc)) { + return -1; +@@ -1780,6 +1783,12 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, + + total = 0; + ++ if (i == VIRTQUEUE_MAX_SIZE) { ++ virtio_error(vdev, "virtio-net unexpected long buffer chain"); ++ err = size; ++ goto err; ++ } ++ + elem = virtqueue_pop(q->rx_vq, sizeof(VirtQueueElement)); + if (!elem) { + if (i) { +@@ -1791,7 +1800,8 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, + n->guest_hdr_len, n->host_hdr_len, + vdev->guest_features); + } +- return -1; ++ err = -1; ++ goto err; + } + + if (elem->in_num < 1) { +@@ -1799,7 +1809,8 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, + "virtio-net receive queue contains no in buffers"); + virtqueue_detach_element(q->rx_vq, elem, 0); + g_free(elem); +- return -1; ++ err = -1; ++ goto err; + } + + sg = elem->in_sg; +@@ -1836,12 +1847,13 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, + if (!n->mergeable_rx_bufs && offset < size) { + virtqueue_unpop(q->rx_vq, elem, total); + g_free(elem); +- return size; ++ err = size; ++ goto err; + } + +- /* signal other side */ +- virtqueue_fill(q->rx_vq, elem, total, i++); +- g_free(elem); ++ elems[i] = elem; ++ lens[i] = total; ++ i++; + } + + if (mhdr_cnt) { +@@ -1851,10 +1863,23 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, + &mhdr.num_buffers, sizeof mhdr.num_buffers); + } + ++ for (j = 0; j < i; j++) { ++ /* signal other side */ ++ virtqueue_fill(q->rx_vq, elems[j], lens[j], j); ++ g_free(elems[j]); ++ } ++ + virtqueue_flush(q->rx_vq, i); + virtio_notify(vdev, q->rx_vq); + + return size; ++ ++err: ++ for (j = 0; j < i; j++) { ++ g_free(elems[j]); ++ } ++ ++ return err; + } + + static ssize_t virtio_net_do_receive(NetClientState *nc, const uint8_t *buf,