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:
parent
9a6945b9db
commit
9cc71e44f4
123
block-introduce-max_hw_iov-for-use-in-sc.patch
Normal file
123
block-introduce-max_hw_iov-for-use-in-sc.patch
Normal 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);
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:75b23e881e084f164f0e4cc474a7141d1a6ec4a3b5a3494ffc5f5e61d516f8a5
|
||||
size 45100
|
||||
oid sha256:898b254c29675506ea3a140a2188cd9036adc5f4d9e9c7997de7852c2408870b
|
||||
size 58180
|
||||
|
59
hmp-Unbreak-change-vnc.patch
Normal file
59
hmp-Unbreak-change-vnc.patch
Normal 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;
|
112
qemu-nbd-Change-default-cache-mode-to-wr.patch
Normal file
112
qemu-nbd-Change-default-cache-mode-to-wr.patch
Normal 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;
|
13
qemu.changes
13
qemu.changes
@ -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>
|
||||
|
||||
|
14
qemu.spec
14
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
|
||||
|
88
target-arm-Don-t-skip-M-profile-reset-en.patch
Normal file
88
target-arm-Don-t-skip-M-profile-reset-en.patch
Normal 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.
|
101
vhost-vsock-fix-migration-issue-when-seq.patch
Normal file
101
vhost-vsock-fix-migration-issue-when-seq.patch
Normal 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 >*/
|
||||
};
|
||||
|
39
virtio-mem-pci-Fix-memory-leak-when-crea.patch
Normal file
39
virtio-mem-pci-Fix-memory-leak-when-crea.patch
Normal 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)
|
121
virtio-net-fix-use-after-unmap-free-for-.patch
Normal file
121
virtio-net-fix-use-after-unmap-free-for-.patch
Normal 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,
|
Loading…
Reference in New Issue
Block a user