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
This commit is contained in:
Li Zhang 2021-10-08 16:10:31 +00:00 committed by Git OBS Bridge
parent 9a6945b9db
commit 9cc71e44f4
10 changed files with 672 additions and 2 deletions

View File

@ -0,0 +1,123 @@
From: Paolo Bonzini <pbonzini@redhat.com>
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 <pasic@linux.ibm.com>
Cc: Hanna Reitz <hreitz@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>
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 <pbonzini@redhat.com>
Message-Id: <20210923130436.1187591-1-pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Li Zhang <li.zhang@suse.com>
---
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);

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:75b23e881e084f164f0e4cc474a7141d1a6ec4a3b5a3494ffc5f5e61d516f8a5
size 45100
oid sha256:898b254c29675506ea3a140a2188cd9036adc5f4d9e9c7997de7852c2408870b
size 58180

View File

@ -0,0 +1,59 @@
From: Markus Armbruster <armbru@redhat.com>
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 <armbru@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Message-Id: <20210909081219.308065-2-armbru@redhat.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Li Zhang <li.zhang@suse.com>
---
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;

View File

@ -0,0 +1,112 @@
From: Nir Soffer <nirsof@gmail.com>
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 <nsoffer@redhat.com>
Message-Id: <20210813205519.50518-1-nsoffer@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Li Zhang <li.zhang@suse.com>
---
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;

View File

@ -1,3 +1,16 @@
-------------------------------------------------------------------
Fri Oct 8 13:48:40 UTC 2021 - Li Zhang <li.zhang@suse.com>
- 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 <jose.ziviani@suse.com>

View File

@ -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

View File

@ -0,0 +1,88 @@
From: Peter Maydell <peter.maydell@linaro.org>
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 <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210914120725.24992-2-peter.maydell@linaro.org
Signed-off-by: Li Zhang <li.zhang@suse.com>
---
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.

View File

@ -0,0 +1,101 @@
From: Stefano Garzarella <sgarzare@redhat.com>
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 <jiang.wang@bytedance.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Message-Id: <20210921161642.206461-2-sgarzare@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Li Zhang <li.zhang@suse.com>
---
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 >*/
};

View File

@ -0,0 +1,39 @@
From: David Hildenbrand <david@redhat.com>
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 <david@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20210929162445.64060-2-david@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Li Zhang <li.zhang@suse.com>
---
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)

View File

@ -0,0 +1,121 @@
From: Jason Wang <jasowang@redhat.com>
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 <alxndr@bu.edu>
Fixes: fbe78f4f55c6 ("virtio-net support")
Cc: qemu-stable@nongnu.org
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Li Zhang <li.zhang@suse.com>
---
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,