* Sun Jul 25 2021 Miroslav Rezanina <mrezanin@redhat.com> - 6.0.0-10

- kvm-s390x-css-Introduce-an-ESW-struct.patch [bz#1957194]
- kvm-s390x-css-Split-out-the-IRB-sense-data.patch [bz#1957194]
- kvm-s390x-css-Refactor-IRB-construction.patch [bz#1957194]
- kvm-s390x-css-Add-passthrough-IRB.patch [bz#1957194]
- kvm-vhost-user-blk-Fail-gracefully-on-too-large-queue-si.patch [bz#1957194]
- kvm-vhost-user-blk-Make-sure-to-set-Error-on-realize-fai.patch [bz#1957194]
- kvm-vhost-user-blk-Don-t-reconnect-during-initialisation.patch [bz#1957194]
- kvm-vhost-user-blk-Improve-error-reporting-in-realize.patch [bz#1957194]
- kvm-vhost-user-blk-Get-more-feature-flags-from-vhost-dev.patch [bz#1957194]
- kvm-virtio-Fail-if-iommu_platform-is-requested-but-unsup.patch [bz#1957194]
- kvm-vhost-user-blk-Check-that-num-queues-is-supported-by.patch [bz#1957194]
- kvm-vhost-user-Fix-backends-without-multiqueue-support.patch [bz#1957194]
- kvm-file-posix-fix-max_iov-for-dev-sg-devices.patch [bz#1957194]
- kvm-scsi-generic-pass-max_segments-via-max_iov-field-in-.patch [bz#1957194]
- kvm-osdep-provide-ROUND_DOWN-macro.patch [bz#1957194]
- kvm-block-backend-align-max_transfer-to-request-alignmen.patch [bz#1957194]
- kvm-block-add-max_hw_transfer-to-BlockLimits.patch [bz#1957194]
- kvm-file-posix-try-BLKSECTGET-on-block-devices-too-do-no.patch [bz#1957194]
- kvm-block-Add-option-to-use-driver-whitelist-even-in-too.patch [bz#1957782]
- kvm-spec-Restrict-block-drivers-in-tools.patch [bz#1957782]
- kvm-Move-tools-to-separate-package.patch [bz#1972285]
- kvm-Split-qemu-pr-helper-to-separate-package.patch [bz#1972300]
- kvm-spec-RPM_BUILD_ROOT-buildroot.patch [bz#1973029]
- kvm-spec-More-use-of-name-instead-of-qemu-kvm.patch [bz#1973029]
- kvm-spec-Use-qemu-pr-helper.service-from-qemu.git.patch [bz#1973029]
- kvm-spec-Use-_sourcedir-for-referencing-sources.patch [bz#1973029]
- kvm-spec-Add-tools_only.patch [bz#1973029]
- kvm-spec-build-Add-run_configure-helper.patch [bz#1973029]
- kvm-spec-build-Disable-more-bits-with-disable_everything.patch [bz#1973029]
- kvm-spec-build-Add-macros-for-some-configure-parameters.patch [bz#1973029]
- kvm-spec-files-Move-qemu-guest-agent-and-qemu-img-earlie.patch [bz#1973029]
- kvm-spec-install-Remove-redundant-bits.patch [bz#1973029]
- kvm-spec-install-Add-modprobe_kvm_conf-macro.patch [bz#1973029]
- kvm-spec-install-Remove-qemu-guest-agent-etc-qemu-kvm-us.patch [bz#1973029]
- kvm-spec-install-clean-up-qemu-ga-section.patch [bz#1973029]
- kvm-spec-install-Use-a-single-tools_only-section.patch [bz#1973029]
- kvm-spec-Make-tools_only-not-cross-spec-sections.patch [bz#1973029]
- kvm-spec-install-Limit-time-spent-in-qemu_kvm_build.patch [bz#1973029]
- kvm-spec-misc-syntactic-merges-with-Fedora.patch [bz#1973029]
- kvm-spec-Use-Fedora-s-pattern-for-specifying-rc-version.patch [bz#1973029]
- kvm-spec-files-don-t-use-fine-grained-docs-file-list.patch [bz#1973029]
- kvm-spec-files-Add-licenses-to-qemu-common-too.patch [bz#1973029]
- kvm-spec-install-Drop-python3-shebang-fixup.patch [bz#1973029]
- Resolves: bz#1957194
  (Synchronize RHEL-AV 8.5.0 changes to RHEL 9.0.0 Beta)
- Resolves: bz#1957782
  (VMDK support should be read-only)
- Resolves: bz#1972285
  (Split out a qemu-kvm-tools subpackage)
- Resolves: bz#1972300
  (Split out a qemu-pr-helper subpackage)
- Resolves: bz#1973029
  (Spec file cleanups)
This commit is contained in:
Miroslav Rezanina 2021-07-25 22:54:48 -04:00
parent 0e98626e1b
commit 88586bd480
22 changed files with 2197 additions and 409 deletions

View File

@ -0,0 +1,121 @@
From 0739f735f99a6f1760a422023c262c1aa542a2e5 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Fri, 9 Jul 2021 18:41:41 +0200
Subject: [PATCH 19/43] block: Add option to use driver whitelist even in tools
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Kevin Wolf <None>
RH-MergeRequest: 26: block: Disable unsupported/read-only block drivers even in tools
RH-Commit: [1/2] 6755d5ff4ef43f275ae530de2b2a568ffd2d3497 (kmwolf/centos-qemu-kvm)
RH-Bugzilla: 1957782
RH-Acked-by: Max Reitz <None>
RH-Acked-by: Richard W.M. Jones <None>
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Currently, the block driver whitelists are only applied for the system
emulator. All other binaries still give unrestricted access to all block
drivers. There are use cases where this made sense because the main
concern was avoiding customers running VMs on less optimised block
drivers and getting bad performance. Allowing the same image format e.g.
as a target for 'qemu-img convert' is not a problem then.
However, if the concern is the supportability of the driver in general,
either in full or when used read-write, not applying the list driver
whitelist in tools doesn't help - especially since qemu-nbd and
qemu-storage-daemon now give access to more or less the same operations
in block drivers as running a system emulator.
In order to address this, introduce a new configure option that enforces
the driver whitelist in all binaries.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20210709164141.254097-1-kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit e5f05f8c375157211c7da625a0d3f3ccdb4957d5)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 3 +++
configure | 14 ++++++++++++--
meson.build | 1 +
3 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/block.c b/block.c
index c5b887cec1..76ecede5af 100644
--- a/block.c
+++ b/block.c
@@ -5817,6 +5817,9 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
void bdrv_init(void)
{
+#ifdef CONFIG_BDRV_WHITELIST_TOOLS
+ use_bdrv_whitelist = 1;
+#endif
module_call_init(MODULE_INIT_BLOCK);
}
diff --git a/configure b/configure
index 53b2fa583a..7edc08afb3 100755
--- a/configure
+++ b/configure
@@ -243,6 +243,7 @@ cross_prefix=""
audio_drv_list=""
block_drv_rw_whitelist=""
block_drv_ro_whitelist=""
+block_drv_whitelist_tools="no"
host_cc="cc"
audio_win_int=""
libs_qga=""
@@ -1029,6 +1030,10 @@ for opt do
;;
--block-drv-ro-whitelist=*) block_drv_ro_whitelist=$(echo "$optarg" | sed -e 's/,/ /g')
;;
+ --enable-block-drv-whitelist-in-tools) block_drv_whitelist_tools="yes"
+ ;;
+ --disable-block-drv-whitelist-in-tools) block_drv_whitelist_tools="no"
+ ;;
--enable-debug-tcg) debug_tcg="yes"
;;
--disable-debug-tcg) debug_tcg="no"
@@ -1764,10 +1769,12 @@ Advanced options (experts only):
--block-drv-whitelist=L Same as --block-drv-rw-whitelist=L
--block-drv-rw-whitelist=L
set block driver read-write whitelist
- (affects only QEMU, not qemu-img)
+ (by default affects only QEMU, not tools like qemu-img)
--block-drv-ro-whitelist=L
set block driver read-only whitelist
- (affects only QEMU, not qemu-img)
+ (by default affects only QEMU, not tools like qemu-img)
+ --enable-block-drv-whitelist-in-tools
+ use block whitelist also in tools instead of only QEMU
--enable-trace-backends=B Set trace backend
Available backends: $trace_backend_list
--with-trace-file=NAME Full PATH,NAME of file to store traces
@@ -5571,6 +5578,9 @@ if test "$audio_win_int" = "yes" ; then
fi
echo "CONFIG_BDRV_RW_WHITELIST=$block_drv_rw_whitelist" >> $config_host_mak
echo "CONFIG_BDRV_RO_WHITELIST=$block_drv_ro_whitelist" >> $config_host_mak
+if test "$block_drv_whitelist_tools" = "yes" ; then
+ echo "CONFIG_BDRV_WHITELIST_TOOLS=y" >> $config_host_mak
+fi
if test "$xfs" = "yes" ; then
echo "CONFIG_XFS=y" >> $config_host_mak
fi
diff --git a/meson.build b/meson.build
index 06c15bd6d2..49b8164ade 100644
--- a/meson.build
+++ b/meson.build
@@ -2606,6 +2606,7 @@ summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1
if have_block
summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
+ summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
summary_info += {'VirtFS support': have_virtfs}
summary_info += {'build virtiofs daemon': have_virtiofsd}
summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
--
2.27.0

View File

@ -0,0 +1,131 @@
From 6773549977d94c504ec76aed67506ae85adff973 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 16 Jul 2021 16:51:33 -0400
Subject: [PATCH 17/43] block: add max_hw_transfer to BlockLimits
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
For block host devices, I/O can happen through either the kernel file
descriptor I/O system calls (preadv/pwritev, io_submit, io_uring)
or the SCSI passthrough ioctl SG_IO.
In the latter case, the size of each transfer can be limited by the
HBA, while for file descriptor I/O the kernel is able to split and
merge I/O in smaller pieces as needed. Applying the HBA limits to
file descriptor I/O results in more system calls and suboptimal
performance, so this patch splits the max_transfer limit in two:
max_transfer remains valid and is used in general, while max_hw_transfer
is limited to the maximum hardware size. max_hw_transfer can then be
included by the scsi-generic driver in the block limits page, to ensure
that the stricter hardware limit is used.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 24b36e9813ec15da7db62e3b3621730710c5f020)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
block/block-backend.c | 13 +++++++++++++
block/file-posix.c | 2 +-
block/io.c | 2 ++
hw/scsi/scsi-generic.c | 2 +-
include/block/block_int.h | 7 +++++++
include/sysemu/block-backend.h | 1 +
6 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 136cc602c5..b5f5b4b048 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1939,6 +1939,19 @@ uint32_t blk_get_request_alignment(BlockBackend *blk)
return bs ? bs->bl.request_alignment : BDRV_SECTOR_SIZE;
}
+/* Returns the maximum hardware transfer length, in bytes; guaranteed nonzero */
+uint64_t blk_get_max_hw_transfer(BlockBackend *blk)
+{
+ BlockDriverState *bs = blk_bs(blk);
+ uint64_t max = INT_MAX;
+
+ if (bs) {
+ max = MIN_NON_ZERO(max, bs->bl.max_hw_transfer);
+ max = MIN_NON_ZERO(max, bs->bl.max_transfer);
+ }
+ return ROUND_DOWN(max, blk_get_request_alignment(blk));
+}
+
/* Returns the maximum transfer length, in bytes; guaranteed nonzero */
uint32_t blk_get_max_transfer(BlockBackend *blk)
{
diff --git a/block/file-posix.c b/block/file-posix.c
index 1a6c799e19..44325a635d 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1258,7 +1258,7 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
int ret = sg_get_max_transfer_length(s->fd);
if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) {
- bs->bl.max_transfer = pow2floor(ret);
+ bs->bl.max_hw_transfer = pow2floor(ret);
}
ret = sg_get_max_segments(s->fd);
diff --git a/block/io.c b/block/io.c
index ca2dca3007..a4b2e3adf1 100644
--- a/block/io.c
+++ b/block/io.c
@@ -126,6 +126,8 @@ static void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src)
{
dst->opt_transfer = MAX(dst->opt_transfer, src->opt_transfer);
dst->max_transfer = MIN_NON_ZERO(dst->max_transfer, src->max_transfer);
+ dst->max_hw_transfer = MIN_NON_ZERO(dst->max_hw_transfer,
+ src->max_hw_transfer);
dst->opt_mem_alignment = MAX(dst->opt_mem_alignment,
src->opt_mem_alignment);
dst->min_mem_alignment = MAX(dst->min_mem_alignment,
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 82e1e2ee79..3762dce749 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -179,7 +179,7 @@ static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s)
(r->req.cmd.buf[1] & 0x01)) {
page = r->req.cmd.buf[2];
if (page == 0xb0) {
- uint32_t max_transfer = blk_get_max_transfer(s->conf.blk);
+ uint64_t max_transfer = blk_get_max_hw_transfer(s->conf.blk);
uint32_t max_iov = blk_get_max_iov(s->conf.blk);
assert(max_transfer);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 88e4111939..09d8630ec4 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -695,6 +695,13 @@ typedef struct BlockLimits {
* clamped down. */
uint32_t max_transfer;
+ /* Maximal hardware transfer length in bytes. Applies whenever
+ * transfers to the device bypass the kernel I/O scheduler, for
+ * example with SG_IO. If larger than max_transfer or if zero,
+ * blk_get_max_hw_transfer will fall back to max_transfer.
+ */
+ uint64_t max_hw_transfer;
+
/* 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 5423e3d9c6..9ac5f7bbd3 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -208,6 +208,7 @@ void blk_eject(BlockBackend *blk, bool eject_flag);
int blk_get_flags(BlockBackend *blk);
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);
void blk_set_guest_block_size(BlockBackend *blk, int align);
void *blk_try_blockalign(BlockBackend *blk, size_t size);
--
2.27.0

View File

@ -0,0 +1,47 @@
From 643c979c2bfa0fc3c45ec8ec5f05a77e0b075356 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 16 Jul 2021 16:51:32 -0400
Subject: [PATCH 16/43] block-backend: align max_transfer to request alignment
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
Block device requests must be aligned to bs->bl.request_alignment.
It makes sense for drivers to align bs->bl.max_transfer the same
way; however when there is no specified limit, blk_get_max_transfer
just returns INT_MAX. Since the contract of the function does not
specify that INT_MAX means "no maximum", just align the outcome
of the function (whether INT_MAX or bs->bl.max_transfer) before
returning it.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit b99f7fa08a3df8b8a6a907642e5851cdcf43fa9f)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
block/block-backend.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 05d8e5fb5d..136cc602c5 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1943,12 +1943,12 @@ uint32_t blk_get_request_alignment(BlockBackend *blk)
uint32_t blk_get_max_transfer(BlockBackend *blk)
{
BlockDriverState *bs = blk_bs(blk);
- uint32_t max = 0;
+ uint32_t max = INT_MAX;
if (bs) {
- max = bs->bl.max_transfer;
+ max = MIN_NON_ZERO(max, bs->bl.max_transfer);
}
- return MIN_NON_ZERO(max, INT_MAX);
+ return ROUND_DOWN(max, blk_get_request_alignment(blk));
}
int blk_get_max_iov(BlockBackend *blk)
--
2.27.0

View File

@ -0,0 +1,50 @@
From 0111d01afe82c46656a40269bf21eb7702c02a09 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 16 Jul 2021 16:51:29 -0400
Subject: [PATCH 13/43] file-posix: fix max_iov for /dev/sg devices
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
Even though it was only called for devices that have bs->sg set (which
must be character devices), sg_get_max_segments looked at /sys/dev/block
which only works for block devices.
On Linux the sg driver has its own way to provide the maximum number of
iovecs in a scatter/gather list, so add support for it. The block device
path is kept because it will be reinstated in the next patches.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 8ad5ab6148dca8aad297c134c09c84b0b92d45ed)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
block/file-posix.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/block/file-posix.c b/block/file-posix.c
index 20e14f8e96..74d4903dc1 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1204,6 +1204,17 @@ static int sg_get_max_segments(int fd)
goto out;
}
+ if (S_ISCHR(st.st_mode)) {
+ if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) {
+ return ret;
+ }
+ return -ENOTSUP;
+ }
+
+ if (!S_ISBLK(st.st_mode)) {
+ return -ENOTSUP;
+ }
+
sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/max_segments",
major(st.st_rdev), minor(st.st_rdev));
sysfd = open(sysfspath, O_RDONLY);
--
2.27.0

View File

@ -0,0 +1,140 @@
From 9c8493d3a6d2e4d879d1ef67ff1abebd532c87a0 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 16 Jul 2021 16:51:34 -0400
Subject: [PATCH 18/43] file-posix: try BLKSECTGET on block devices too, do not
round to power of 2
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
bs->sg is only true for character devices, but block devices can also
be used with scsi-block and scsi-generic. Unfortunately BLKSECTGET
returns bytes in an int for /dev/sgN devices, and sectors in a short
for block devices, so account for that in the code.
The maximum transfer also need not be a power of 2 (for example I have
seen disks with 1280 KiB maximum transfer) so there's no need to pass
the result through pow2floor.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 18473467d55a20d643b6c9b3a52de42f705b4d35)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
block/file-posix.c | 57 +++++++++++++++++++++++++++-------------------
1 file changed, 33 insertions(+), 24 deletions(-)
diff --git a/block/file-posix.c b/block/file-posix.c
index 44325a635d..7b4ebf65d5 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1173,22 +1173,27 @@ static void raw_reopen_abort(BDRVReopenState *state)
s->reopen_state = NULL;
}
-static int sg_get_max_transfer_length(int fd)
+static int hdev_get_max_hw_transfer(int fd, struct stat *st)
{
#ifdef BLKSECTGET
- int max_bytes = 0;
-
- if (ioctl(fd, BLKSECTGET, &max_bytes) == 0) {
- return max_bytes;
+ if (S_ISBLK(st->st_mode)) {
+ unsigned short max_sectors = 0;
+ if (ioctl(fd, BLKSECTGET, &max_sectors) == 0) {
+ return max_sectors * 512;
+ }
} else {
- return -errno;
+ int max_bytes = 0;
+ if (ioctl(fd, BLKSECTGET, &max_bytes) == 0) {
+ return max_bytes;
+ }
}
+ return -errno;
#else
return -ENOSYS;
#endif
}
-static int sg_get_max_segments(int fd)
+static int hdev_get_max_segments(int fd, struct stat *st)
{
#ifdef CONFIG_LINUX
char buf[32];
@@ -1197,26 +1202,20 @@ static int sg_get_max_segments(int fd)
int ret;
int sysfd = -1;
long max_segments;
- struct stat st;
-
- if (fstat(fd, &st)) {
- ret = -errno;
- goto out;
- }
- if (S_ISCHR(st.st_mode)) {
+ if (S_ISCHR(st->st_mode)) {
if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) {
return ret;
}
return -ENOTSUP;
}
- if (!S_ISBLK(st.st_mode)) {
+ if (!S_ISBLK(st->st_mode)) {
return -ENOTSUP;
}
sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/max_segments",
- major(st.st_rdev), minor(st.st_rdev));
+ major(st->st_rdev), minor(st->st_rdev));
sysfd = open(sysfspath, O_RDONLY);
if (sysfd == -1) {
ret = -errno;
@@ -1253,23 +1252,33 @@ out:
static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
{
BDRVRawState *s = bs->opaque;
+ struct stat st;
- if (bs->sg) {
- int ret = sg_get_max_transfer_length(s->fd);
+ raw_probe_alignment(bs, s->fd, errp);
+ bs->bl.min_mem_alignment = s->buf_align;
+ bs->bl.opt_mem_alignment = MAX(s->buf_align, qemu_real_host_page_size);
+
+ /*
+ * Maximum transfers are best effort, so it is okay to ignore any
+ * errors. That said, based on the man page errors in fstat would be
+ * very much unexpected; the only possible case seems to be ENOMEM.
+ */
+ if (fstat(s->fd, &st)) {
+ return;
+ }
+
+ if (bs->sg || S_ISBLK(st.st_mode)) {
+ int ret = hdev_get_max_hw_transfer(s->fd, &st);
if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) {
- bs->bl.max_hw_transfer = pow2floor(ret);
+ bs->bl.max_hw_transfer = ret;
}
- ret = sg_get_max_segments(s->fd);
+ ret = hdev_get_max_segments(s->fd, &st);
if (ret > 0) {
bs->bl.max_iov = ret;
}
}
-
- raw_probe_alignment(bs, s->fd, errp);
- bs->bl.min_mem_alignment = s->buf_align;
- bs->bl.opt_mem_alignment = MAX(s->buf_align, qemu_real_host_page_size);
}
static int check_for_dasd(int fd)
--
2.27.0

View File

@ -0,0 +1,75 @@
From d9fa07a04ee19ad713b053f6a649178361d822a8 Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 16 Jul 2021 16:51:31 -0400
Subject: [PATCH 15/43] osdep: provide ROUND_DOWN macro
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
osdep.h provides a ROUND_UP macro to hide bitwise operations for the
purpose of rounding a number up to a power of two; add a ROUND_DOWN
macro that does the same with truncation towards zero.
While at it, change the formatting of some comments.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit c9797456f64ce72c03eb2969d97ac1dd4698d91e)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
include/qemu/osdep.h | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index cb2a07e472..e327220992 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -316,11 +316,16 @@ extern "C" {
})
#endif
-/* Round number down to multiple */
+/*
+ * Round number down to multiple. Safe when m is not a power of 2 (see
+ * ROUND_DOWN for a faster version when a power of 2 is guaranteed).
+ */
#define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m))
-/* Round number up to multiple. Safe when m is not a power of 2 (see
- * ROUND_UP for a faster version when a power of 2 is guaranteed) */
+/*
+ * Round number up to multiple. Safe when m is not a power of 2 (see
+ * ROUND_UP for a faster version when a power of 2 is guaranteed).
+ */
#define QEMU_ALIGN_UP(n, m) QEMU_ALIGN_DOWN((n) + (m) - 1, (m))
/* Check if n is a multiple of m */
@@ -337,11 +342,22 @@ extern "C" {
/* Check if pointer p is n-bytes aligned */
#define QEMU_PTR_IS_ALIGNED(p, n) QEMU_IS_ALIGNED((uintptr_t)(p), (n))
-/* Round number up to multiple. Requires that d be a power of 2 (see
+/*
+ * Round number down to multiple. Requires that d be a power of 2 (see
* QEMU_ALIGN_UP for a safer but slower version on arbitrary
- * numbers); works even if d is a smaller type than n. */
+ * numbers); works even if d is a smaller type than n.
+ */
+#ifndef ROUND_DOWN
+#define ROUND_DOWN(n, d) ((n) & -(0 ? (n) : (d)))
+#endif
+
+/*
+ * Round number up to multiple. Requires that d be a power of 2 (see
+ * QEMU_ALIGN_UP for a safer but slower version on arbitrary
+ * numbers); works even if d is a smaller type than n.
+ */
#ifndef ROUND_UP
-#define ROUND_UP(n, d) (((n) + (d) - 1) & -(0 ? (n) : (d)))
+#define ROUND_UP(n, d) ROUND_DOWN((n) + (d) - 1, (d))
#endif
#ifndef DIV_ROUND_UP
--
2.27.0

View File

@ -0,0 +1,127 @@
From 4eb1f0936bfc921cad9af37f1573075148843b1d Mon Sep 17 00:00:00 2001
From: Eric Farman <farman@linux.ibm.com>
Date: Thu, 24 Jun 2021 14:15:16 -0400
Subject: [PATCH 04/43] s390x/css: Add passthrough IRB
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
Wire in the subchannel callback for building the IRB
ESW and ECW space for passthrough devices, and copy
the hardware's ESW into the IRB we are building.
If the hardware presented concurrent sense, then copy
that sense data into the IRB's ECW space.
Signed-off-by: Eric Farman <farman@linux.ibm.com>
Message-Id: <20210617232537.1337506-5-farman@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit c626710fc755628d0d6b88aab0514c9238a84522)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hw/s390x/css.c | 16 +++++++++++++++-
hw/s390x/s390-ccw.c | 1 +
hw/vfio/ccw.c | 4 ++++
include/hw/s390x/css.h | 3 +++
4 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index e77a0e523d..c3150da4f7 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1336,7 +1336,7 @@ static void copy_schib_to_guest(SCHIB *dest, const SCHIB *src)
}
}
-static void copy_esw_to_guest(ESW *dest, const ESW *src)
+void copy_esw_to_guest(ESW *dest, const ESW *src)
{
dest->word0 = cpu_to_be32(src->word0);
dest->erw = cpu_to_be32(src->erw);
@@ -1651,6 +1651,20 @@ static void build_irb_sense_data(SubchDev *sch, IRB *irb)
}
}
+void build_irb_passthrough(SubchDev *sch, IRB *irb)
+{
+ /* Copy ESW from hardware */
+ irb->esw = sch->esw;
+
+ /*
+ * If (irb->esw.erw & ESW_ERW_SENSE) is true, then the contents
+ * of the ECW is sense data. If false, then it is model-dependent
+ * information. Either way, copy it into the IRB for the guest to
+ * read/decide what to do with.
+ */
+ build_irb_sense_data(sch, irb);
+}
+
void build_irb_virtual(SubchDev *sch, IRB *irb)
{
SCHIB *schib = &sch->curr_status;
diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c
index b497571863..39cbea615b 100644
--- a/hw/s390x/s390-ccw.c
+++ b/hw/s390x/s390-ccw.c
@@ -125,6 +125,7 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
}
sch->driver_data = cdev;
sch->do_subchannel_work = do_subchannel_work_passthrough;
+ sch->irb_cb = build_irb_passthrough;
ccw_dev->sch = sch;
ret = css_sch_build_schib(sch, &cdev->hostid);
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index b2df708e4b..5f141d44a4 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -322,6 +322,7 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
SCHIB *schib = &sch->curr_status;
SCSW s;
IRB irb;
+ ESW esw;
int size;
if (!event_notifier_test_and_clear(&vcdev->io_notifier)) {
@@ -372,6 +373,9 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
copy_scsw_to_guest(&s, &irb.scsw);
schib->scsw = s;
+ copy_esw_to_guest(&esw, &irb.esw);
+ sch->esw = esw;
+
/* If a uint check is pending, copy sense data. */
if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
(schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index 7c23a13f3d..10ed1df1bb 100644
--- a/include/hw/s390x/css.h
+++ b/include/hw/s390x/css.h
@@ -141,6 +141,7 @@ struct SubchDev {
void (*irb_cb)(SubchDev *, IRB *);
SenseId id;
void *driver_data;
+ ESW esw;
};
static inline void sch_gen_unit_exception(SubchDev *sch)
@@ -202,6 +203,7 @@ int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id);
unsigned int css_find_free_chpid(uint8_t cssid);
uint16_t css_build_subchannel_id(SubchDev *sch);
void copy_scsw_to_guest(SCSW *dest, const SCSW *src);
+void copy_esw_to_guest(ESW *dest, const ESW *src);
void css_inject_io_interrupt(SubchDev *sch);
void css_reset(void);
void css_reset_sch(SubchDev *sch);
@@ -216,6 +218,7 @@ void css_clear_sei_pending(void);
IOInstEnding s390_ccw_cmd_request(SubchDev *sch);
IOInstEnding do_subchannel_work_virtual(SubchDev *sub);
IOInstEnding do_subchannel_work_passthrough(SubchDev *sub);
+void build_irb_passthrough(SubchDev *sch, IRB *irb);
void build_irb_virtual(SubchDev *sch, IRB *irb);
int s390_ccw_halt(SubchDev *sch);
--
2.27.0

View File

@ -0,0 +1,111 @@
From 9a12329325d94ab56dbab976b4423fe7db0e8d0b Mon Sep 17 00:00:00 2001
From: Eric Farman <farman@linux.ibm.com>
Date: Thu, 24 Jun 2021 14:15:13 -0400
Subject: [PATCH 01/43] s390x/css: Introduce an ESW struct
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
The Interrupt Response Block is comprised of several other
structures concatenated together, but only the 12-byte
Subchannel-Status Word (SCSW) is defined as a proper struct.
Everything else is a simple array of 32-bit words.
Let's define a proper struct for the 20-byte Extended-Status
Word (ESW) so that we can make good decisions about the sense
data that would go into the ECW area for virtual vs
passthrough devices.
[CH: adapted ESW definition to build with mingw, as discussed]
Signed-off-by: Eric Farman <farman@linux.ibm.com>
Message-Id: <20210617232537.1337506-2-farman@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 3fdc622ad79636f3d7f8bed50a53bc28af1850e1)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hw/s390x/css.c | 19 +++++++++++++------
include/hw/s390x/ioinst.h | 12 +++++++++++-
2 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 4149b8e5a7..bd3172a688 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1336,6 +1336,14 @@ static void copy_schib_to_guest(SCHIB *dest, const SCHIB *src)
}
}
+static void copy_esw_to_guest(ESW *dest, const ESW *src)
+{
+ dest->word0 = cpu_to_be32(src->word0);
+ dest->erw = cpu_to_be32(src->erw);
+ dest->word2 = cpu_to_be64(src->word2);
+ dest->word4 = cpu_to_be32(src->word4);
+}
+
IOInstEnding css_do_stsch(SubchDev *sch, SCHIB *schib)
{
int ret;
@@ -1605,9 +1613,8 @@ static void copy_irb_to_guest(IRB *dest, const IRB *src, const PMCW *pmcw,
copy_scsw_to_guest(&dest->scsw, &src->scsw);
- for (i = 0; i < ARRAY_SIZE(dest->esw); i++) {
- dest->esw[i] = cpu_to_be32(src->esw[i]);
- }
+ copy_esw_to_guest(&dest->esw, &src->esw);
+
for (i = 0; i < ARRAY_SIZE(dest->ecw); i++) {
dest->ecw[i] = cpu_to_be32(src->ecw[i]);
}
@@ -1656,9 +1663,9 @@ int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
SCSW_CSTAT_CHN_CTRL_CHK |
SCSW_CSTAT_INTF_CTRL_CHK)) {
irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF;
- irb.esw[0] = 0x04804000;
+ irb.esw.word0 = 0x04804000;
} else {
- irb.esw[0] = 0x00800000;
+ irb.esw.word0 = 0x00800000;
}
/* If a unit check is pending, copy sense data. */
if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
@@ -1671,7 +1678,7 @@ int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
for (i = 0; i < ARRAY_SIZE(irb.ecw); i++) {
irb.ecw[i] = be32_to_cpu(irb.ecw[i]);
}
- irb.esw[1] = 0x01000000 | (sizeof(sch->sense_data) << 8);
+ irb.esw.erw = ESW_ERW_SENSE | (sizeof(sch->sense_data) << 8);
}
}
/* Store the irb to the guest. */
diff --git a/include/hw/s390x/ioinst.h b/include/hw/s390x/ioinst.h
index c6737a30d4..3771fff9d4 100644
--- a/include/hw/s390x/ioinst.h
+++ b/include/hw/s390x/ioinst.h
@@ -123,10 +123,20 @@ typedef struct SCHIB {
uint8_t mda[4];
} QEMU_PACKED SCHIB;
+/* format-0 extended-status word */
+typedef struct ESW {
+ uint32_t word0; /* subchannel logout for format 0 */
+ uint32_t erw;
+ uint64_t word2; /* failing-storage address for format 0 */
+ uint32_t word4; /* secondary-CCW address for format 0 */
+} QEMU_PACKED ESW;
+
+#define ESW_ERW_SENSE 0x01000000
+
/* interruption response block */
typedef struct IRB {
SCSW scsw;
- uint32_t esw[5];
+ ESW esw;
uint32_t ecw[8];
uint32_t emw[8];
} IRB;
--
2.27.0

View File

@ -0,0 +1,144 @@
From 0f4d8c51b51a23a87f1e3e9e764151352f652f3b Mon Sep 17 00:00:00 2001
From: Eric Farman <farman@linux.ibm.com>
Date: Thu, 24 Jun 2021 14:15:15 -0400
Subject: [PATCH 03/43] s390x/css: Refactor IRB construction
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
Currently, all subchannel types have "sense data" copied into
the IRB.ECW space, and a couple flags enabled in the IRB.SCSW
and IRB.ESW. But for passthrough (vfio-ccw) subchannels,
this data isn't populated in the first place, so enabling
those flags leads to unexpected behavior if the guest tries to
process the sense data (zeros) in the IRB.ECW.
Let's add a subchannel callback that builds these portions of
the IRB, and move the existing code into a routine for those
virtual subchannels. The passthrough subchannels will be able
to piggy-back onto this later.
Signed-off-by: Eric Farman <farman@linux.ibm.com>
Message-Id: <20210617232537.1337506-4-farman@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 0599a046acf1b625e97cef0aa702b5d86528c642)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hw/s390x/3270-ccw.c | 1 +
hw/s390x/css.c | 45 +++++++++++++++++++++++++++---------------
hw/s390x/virtio-ccw.c | 1 +
include/hw/s390x/css.h | 2 ++
4 files changed, 33 insertions(+), 16 deletions(-)
diff --git a/hw/s390x/3270-ccw.c b/hw/s390x/3270-ccw.c
index f3e7342b1e..9efee591f9 100644
--- a/hw/s390x/3270-ccw.c
+++ b/hw/s390x/3270-ccw.c
@@ -130,6 +130,7 @@ static void emulated_ccw_3270_realize(DeviceState *ds, Error **errp)
EMULATED_CCW_3270_CHPID_TYPE);
sch->do_subchannel_work = do_subchannel_work_virtual;
sch->ccw_cb = emulated_ccw_3270_cb;
+ sch->irb_cb = build_irb_virtual;
ck->init(dev, &err);
if (err) {
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index fac7d5b39d..e77a0e523d 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1651,6 +1651,30 @@ static void build_irb_sense_data(SubchDev *sch, IRB *irb)
}
}
+void build_irb_virtual(SubchDev *sch, IRB *irb)
+{
+ SCHIB *schib = &sch->curr_status;
+ uint16_t stctl = schib->scsw.ctrl & SCSW_CTRL_MASK_STCTL;
+
+ if (stctl & SCSW_STCTL_STATUS_PEND) {
+ if (schib->scsw.cstat & (SCSW_CSTAT_DATA_CHECK |
+ SCSW_CSTAT_CHN_CTRL_CHK |
+ SCSW_CSTAT_INTF_CTRL_CHK)) {
+ irb->scsw.flags |= SCSW_FLAGS_MASK_ESWF;
+ irb->esw.word0 = 0x04804000;
+ } else {
+ irb->esw.word0 = 0x00800000;
+ }
+ /* If a unit check is pending, copy sense data. */
+ if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
+ (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
+ irb->scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
+ build_irb_sense_data(sch, irb);
+ irb->esw.erw = ESW_ERW_SENSE | (sizeof(sch->sense_data) << 8);
+ }
+ }
+}
+
int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
{
SCHIB *schib = &sch->curr_status;
@@ -1669,23 +1693,12 @@ int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
/* Copy scsw from current status. */
irb.scsw = schib->scsw;
- if (stctl & SCSW_STCTL_STATUS_PEND) {
- if (schib->scsw.cstat & (SCSW_CSTAT_DATA_CHECK |
- SCSW_CSTAT_CHN_CTRL_CHK |
- SCSW_CSTAT_INTF_CTRL_CHK)) {
- irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF;
- irb.esw.word0 = 0x04804000;
- } else {
- irb.esw.word0 = 0x00800000;
- }
- /* If a unit check is pending, copy sense data. */
- if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
- (schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
- irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
- build_irb_sense_data(sch, &irb);
- irb.esw.erw = ESW_ERW_SENSE | (sizeof(sch->sense_data) << 8);
- }
+
+ /* Build other IRB data, if necessary */
+ if (sch->irb_cb) {
+ sch->irb_cb(sch, &irb);
}
+
/* Store the irb to the guest. */
p = schib->pmcw;
copy_irb_to_guest(target_irb, &irb, &p, irb_len);
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 8195f3546e..5a1eb39325 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -754,6 +754,7 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
sch->id.reserved = 0xff;
sch->id.cu_type = VIRTIO_CCW_CU_TYPE;
sch->do_subchannel_work = do_subchannel_work_virtual;
+ sch->irb_cb = build_irb_virtual;
ccw_dev->sch = sch;
dev->indicators = NULL;
dev->revision = -1;
diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h
index bba7593d2e..7c23a13f3d 100644
--- a/include/hw/s390x/css.h
+++ b/include/hw/s390x/css.h
@@ -138,6 +138,7 @@ struct SubchDev {
int (*ccw_cb) (SubchDev *, CCW1);
void (*disable_cb)(SubchDev *);
IOInstEnding (*do_subchannel_work) (SubchDev *);
+ void (*irb_cb)(SubchDev *, IRB *);
SenseId id;
void *driver_data;
};
@@ -215,6 +216,7 @@ void css_clear_sei_pending(void);
IOInstEnding s390_ccw_cmd_request(SubchDev *sch);
IOInstEnding do_subchannel_work_virtual(SubchDev *sub);
IOInstEnding do_subchannel_work_passthrough(SubchDev *sub);
+void build_irb_virtual(SubchDev *sch, IRB *irb);
int s390_ccw_halt(SubchDev *sch);
int s390_ccw_clear(SubchDev *sch);
--
2.27.0

View File

@ -0,0 +1,63 @@
From a987dfced200adf1e4c2d3c39f0b5da0fb7e6ead Mon Sep 17 00:00:00 2001
From: Eric Farman <farman@linux.ibm.com>
Date: Thu, 24 Jun 2021 14:15:14 -0400
Subject: [PATCH 02/43] s390x/css: Split out the IRB sense data
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
Let's move this logic into its own routine,
so it can be reused later.
Signed-off-by: Eric Farman <farman@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20210617232537.1337506-3-farman@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 1b01dedaed41c2ca6129475c22b7b778b109fae8)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hw/s390x/css.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index bd3172a688..fac7d5b39d 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -1640,6 +1640,17 @@ static void copy_irb_to_guest(IRB *dest, const IRB *src, const PMCW *pmcw,
*irb_len = sizeof(*dest);
}
+static void build_irb_sense_data(SubchDev *sch, IRB *irb)
+{
+ int i;
+
+ /* Attention: sense_data is already BE! */
+ memcpy(irb->ecw, sch->sense_data, sizeof(sch->sense_data));
+ for (i = 0; i < ARRAY_SIZE(irb->ecw); i++) {
+ irb->ecw[i] = be32_to_cpu(irb->ecw[i]);
+ }
+}
+
int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
{
SCHIB *schib = &sch->curr_status;
@@ -1670,14 +1681,8 @@ int css_do_tsch_get_irb(SubchDev *sch, IRB *target_irb, int *irb_len)
/* If a unit check is pending, copy sense data. */
if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
(schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
- int i;
-
irb.scsw.flags |= SCSW_FLAGS_MASK_ESWF | SCSW_FLAGS_MASK_ECTL;
- /* Attention: sense_data is already BE! */
- memcpy(irb.ecw, sch->sense_data, sizeof(sch->sense_data));
- for (i = 0; i < ARRAY_SIZE(irb.ecw); i++) {
- irb.ecw[i] = be32_to_cpu(irb.ecw[i]);
- }
+ build_irb_sense_data(sch, &irb);
irb.esw.erw = ESW_ERW_SENSE | (sizeof(sch->sense_data) << 8);
}
}
--
2.27.0

View File

@ -0,0 +1,64 @@
From 05038edf628c6bca7cef061b7b1fac2b0b2163af Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Fri, 16 Jul 2021 16:51:30 -0400
Subject: [PATCH 14/43] scsi-generic: pass max_segments via max_iov field in
BlockLimits
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
I/O to a disk via read/write is not limited by the number of segments allowed
by the host adapter; the kernel can split requests if needed, and the limit
imposed by the host adapter can be very low (256k or so) to avoid that SG_IO
returns EINVAL if memory is heavily fragmented.
Since this value is only interesting for SG_IO-based I/O, do not include
it in the max_transfer and only take it into account when patching the
block limits VPD page in the scsi-generic device.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
(cherry picked from commit 01ef8185b809af9d287e1a03a3f9d8ea8231118a)
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
block/file-posix.c | 3 +--
hw/scsi/scsi-generic.c | 6 ++++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/block/file-posix.c b/block/file-posix.c
index 74d4903dc1..1a6c799e19 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1263,8 +1263,7 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
ret = sg_get_max_segments(s->fd);
if (ret > 0) {
- bs->bl.max_transfer = MIN(bs->bl.max_transfer,
- ret * qemu_real_host_page_size);
+ bs->bl.max_iov = ret;
}
}
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 98c30c5d5c..82e1e2ee79 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -179,10 +179,12 @@ static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s)
(r->req.cmd.buf[1] & 0x01)) {
page = r->req.cmd.buf[2];
if (page == 0xb0) {
- uint32_t max_transfer =
- blk_get_max_transfer(s->conf.blk) / s->blocksize;
+ uint32_t max_transfer = blk_get_max_transfer(s->conf.blk);
+ uint32_t max_iov = blk_get_max_iov(s->conf.blk);
assert(max_transfer);
+ max_transfer = MIN_NON_ZERO(max_transfer, max_iov * qemu_real_host_page_size)
+ / s->blocksize;
stl_be_p(&r->buf[8], max_transfer);
/* Also take care of the opt xfer len. */
stl_be_p(&r->buf[12],
--
2.27.0

View File

@ -0,0 +1,46 @@
From de25a5f05b76ca99299e09dabe04e7d59b9bed79 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 12 Jul 2021 10:22:32 -0400
Subject: [PATCH 12/43] vhost-user: Fix backends without multiqueue support
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
dev->max_queues was never initialised for backends that don't support
VHOST_USER_PROTOCOL_F_MQ, so it would use 0 as the maximum number of
queues to check against and consequently fail for any such backend.
Set it to 1 if the backend doesn't have multiqueue support.
Fixes: c90bd505a3e8210c23d69fecab9ee6f56ec4a161
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20210705171429.29286-1-kwolf@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 84affad1fd4c5251d7cccf4df43b29e9157983a9)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hw/virtio/vhost-user.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index ee57abe045..53f50adcba 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -1908,7 +1908,10 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque)
if (err < 0) {
return err;
}
+ } else {
+ dev->max_queues = 1;
}
+
if (dev->num_queues && dev->max_queues < dev->num_queues) {
error_report("The maximum number of queues supported by the "
"backend is %" PRIu64, dev->max_queues);
--
2.27.0

View File

@ -0,0 +1,83 @@
From f3cec652012b0b5ab1d881f6377719b0984bce63 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 12 Jul 2021 10:22:31 -0400
Subject: [PATCH 11/43] vhost-user-blk: Check that num-queues is supported by
backend
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
Creating a device with a number of queues that isn't supported by the
backend is pointless, the device won't work properly and the error
messages are rather confusing.
Just fail to create the device if num-queues is higher than what the
backend supports.
Since the relationship between num-queues and the number of virtqueues
depends on the specific device, this is an additional value that needs
to be initialised by the device. For convenience, allow leaving it 0 if
the check should be skipped. This makes sense for vhost-user-net where
separate vhost devices are used for the queues and custom initialisation
code is needed to perform the check.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1935031
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Message-Id: <20210429171316.162022-7-kwolf@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit c90bd505a3e8210c23d69fecab9ee6f56ec4a161)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hw/block/vhost-user-blk.c | 1 +
hw/virtio/vhost-user.c | 5 +++++
include/hw/virtio/vhost.h | 2 ++
3 files changed, 8 insertions(+)
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index c7e502f4c7..c6210fad0c 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -324,6 +324,7 @@ static int vhost_user_blk_connect(DeviceState *dev, Error **errp)
}
s->connected = true;
+ s->dev.num_queues = s->num_queues;
s->dev.nvqs = s->num_queues;
s->dev.vqs = s->vhost_vqs;
s->dev.vq_index = 0;
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index ded0c10453..ee57abe045 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -1909,6 +1909,11 @@ static int vhost_user_backend_init(struct vhost_dev *dev, void *opaque)
return err;
}
}
+ if (dev->num_queues && dev->max_queues < dev->num_queues) {
+ error_report("The maximum number of queues supported by the "
+ "backend is %" PRIu64, dev->max_queues);
+ return -EINVAL;
+ }
if (virtio_has_feature(features, VIRTIO_F_IOMMU_PLATFORM) &&
!(virtio_has_feature(dev->protocol_features,
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index 4a8bc75415..21a9a52088 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -74,6 +74,8 @@ struct vhost_dev {
int nvqs;
/* the first virtqueue which would be used by this vhost dev */
int vq_index;
+ /* if non-zero, minimum required value for max_queues */
+ int num_queues;
uint64_t features;
uint64_t acked_features;
uint64_t backend_features;
--
2.27.0

View File

@ -0,0 +1,179 @@
From 5d39cb265db6ea2159662a2d071d340712940d33 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 12 Jul 2021 10:22:27 -0400
Subject: [PATCH 07/43] vhost-user-blk: Don't reconnect during initialisation
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
This is a partial revert of commits 77542d43149 and bc79c87bcde.
Usually, an error during initialisation means that the configuration was
wrong. Reconnecting won't make the error go away, but just turn the
error condition into an endless loop. Avoid this and return errors
again.
Additionally, calling vhost_user_blk_disconnect() from the chardev event
handler could result in use-after-free because none of the
initialisation code expects that the device could just go away in the
middle. So removing the call fixes crashes in several places.
For example, using a num-queues setting that is incompatible with the
backend would result in a crash like this (dereferencing dev->opaque,
which is already NULL):
#0 0x0000555555d0a4bd in vhost_user_read_cb (source=0x5555568f4690, condition=(G_IO_IN | G_IO_HUP), opaque=0x7fffffffcbf0) at ../hw/virtio/vhost-user.c:313
#1 0x0000555555d950d3 in qio_channel_fd_source_dispatch (source=0x555557c3f750, callback=0x555555d0a478 <vhost_user_read_cb>, user_data=0x7fffffffcbf0) at ../io/channel-watch.c:84
#2 0x00007ffff7b32a9f in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
#3 0x00007ffff7b84a98 in g_main_context_iterate.constprop () at /lib64/libglib-2.0.so.0
#4 0x00007ffff7b32163 in g_main_loop_run () at /lib64/libglib-2.0.so.0
#5 0x0000555555d0a724 in vhost_user_read (dev=0x555557bc62f8, msg=0x7fffffffcc50) at ../hw/virtio/vhost-user.c:402
#6 0x0000555555d0ee6b in vhost_user_get_config (dev=0x555557bc62f8, config=0x555557bc62ac "", config_len=60) at ../hw/virtio/vhost-user.c:2133
#7 0x0000555555d56d46 in vhost_dev_get_config (hdev=0x555557bc62f8, config=0x555557bc62ac "", config_len=60) at ../hw/virtio/vhost.c:1566
#8 0x0000555555cdd150 in vhost_user_blk_device_realize (dev=0x555557bc60b0, errp=0x7fffffffcf90) at ../hw/block/vhost-user-blk.c:510
#9 0x0000555555d08f6d in virtio_device_realize (dev=0x555557bc60b0, errp=0x7fffffffcff0) at ../hw/virtio/virtio.c:3660
Note that this removes the ability to reconnect during initialisation
(but not during operation) when there is no permanent error, but the
backend restarts, as the implementation was buggy. This feature can be
added back in a follow-up series after changing error paths to
distinguish cases where retrying could help from cases with permanent
errors.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20210429171316.162022-3-kwolf@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit dabefdd6abcbc7d858e9413e4734aab2e0b5c8d9)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hw/block/vhost-user-blk.c | 59 +++++++++++----------------------------
1 file changed, 17 insertions(+), 42 deletions(-)
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 7c85248a7b..c0b9958da1 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -50,6 +50,8 @@ static const int user_feature_bits[] = {
VHOST_INVALID_FEATURE_BIT
};
+static void vhost_user_blk_event(void *opaque, QEMUChrEvent event);
+
static void vhost_user_blk_update_config(VirtIODevice *vdev, uint8_t *config)
{
VHostUserBlk *s = VHOST_USER_BLK(vdev);
@@ -362,19 +364,6 @@ static void vhost_user_blk_disconnect(DeviceState *dev)
vhost_dev_cleanup(&s->dev);
}
-static void vhost_user_blk_event(void *opaque, QEMUChrEvent event,
- bool realized);
-
-static void vhost_user_blk_event_realize(void *opaque, QEMUChrEvent event)
-{
- vhost_user_blk_event(opaque, event, false);
-}
-
-static void vhost_user_blk_event_oper(void *opaque, QEMUChrEvent event)
-{
- vhost_user_blk_event(opaque, event, true);
-}
-
static void vhost_user_blk_chr_closed_bh(void *opaque)
{
DeviceState *dev = opaque;
@@ -382,12 +371,11 @@ static void vhost_user_blk_chr_closed_bh(void *opaque)
VHostUserBlk *s = VHOST_USER_BLK(vdev);
vhost_user_blk_disconnect(dev);
- qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL,
- vhost_user_blk_event_oper, NULL, opaque, NULL, true);
+ qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL, vhost_user_blk_event,
+ NULL, opaque, NULL, true);
}
-static void vhost_user_blk_event(void *opaque, QEMUChrEvent event,
- bool realized)
+static void vhost_user_blk_event(void *opaque, QEMUChrEvent event)
{
DeviceState *dev = opaque;
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
@@ -401,17 +389,7 @@ static void vhost_user_blk_event(void *opaque, QEMUChrEvent event,
}
break;
case CHR_EVENT_CLOSED:
- /*
- * Closing the connection should happen differently on device
- * initialization and operation stages.
- * On initalization, we want to re-start vhost_dev initialization
- * from the very beginning right away when the connection is closed,
- * so we clean up vhost_dev on each connection closing.
- * On operation, we want to postpone vhost_dev cleanup to let the
- * other code perform its own cleanup sequence using vhost_dev data
- * (e.g. vhost_dev_set_log).
- */
- if (realized && !runstate_check(RUN_STATE_SHUTDOWN)) {
+ if (!runstate_check(RUN_STATE_SHUTDOWN)) {
/*
* A close event may happen during a read/write, but vhost
* code assumes the vhost_dev remains setup, so delay the
@@ -431,8 +409,6 @@ static void vhost_user_blk_event(void *opaque, QEMUChrEvent event,
* knowing its type (in this case vhost-user).
*/
s->dev.started = false;
- } else {
- vhost_user_blk_disconnect(dev);
}
break;
case CHR_EVENT_BREAK:
@@ -489,33 +465,32 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
s->vhost_vqs = g_new0(struct vhost_virtqueue, s->num_queues);
s->connected = false;
- qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL,
- vhost_user_blk_event_realize, NULL, (void *)dev,
- NULL, true);
-
-reconnect:
if (qemu_chr_fe_wait_connected(&s->chardev, errp) < 0) {
goto virtio_err;
}
- /* check whether vhost_user_blk_connect() failed or not */
- if (!s->connected) {
- goto reconnect;
+ if (vhost_user_blk_connect(dev) < 0) {
+ error_setg(errp, "vhost-user-blk: could not connect");
+ qemu_chr_fe_disconnect(&s->chardev);
+ goto virtio_err;
}
+ assert(s->connected);
ret = vhost_dev_get_config(&s->dev, (uint8_t *)&s->blkcfg,
sizeof(struct virtio_blk_config));
if (ret < 0) {
- error_report("vhost-user-blk: get block config failed");
- goto reconnect;
+ error_setg(errp, "vhost-user-blk: get block config failed");
+ goto vhost_err;
}
- /* we're fully initialized, now we can operate, so change the handler */
+ /* we're fully initialized, now we can operate, so add the handler */
qemu_chr_fe_set_handlers(&s->chardev, NULL, NULL,
- vhost_user_blk_event_oper, NULL, (void *)dev,
+ vhost_user_blk_event, NULL, (void *)dev,
NULL, true);
return;
+vhost_err:
+ vhost_dev_cleanup(&s->dev);
virtio_err:
g_free(s->vhost_vqs);
s->vhost_vqs = NULL;
--
2.27.0

View File

@ -0,0 +1,55 @@
From bb551b71851c8d5a37b29aae373a99e97885a4df Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 12 Jul 2021 10:22:25 -0400
Subject: [PATCH 05/43] vhost-user-blk: Fail gracefully on too large queue size
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
virtio_add_queue() aborts when queue_size > VIRTQUEUE_MAX_SIZE, so
vhost_user_blk_device_realize() should check this before calling it.
Simple reproducer:
qemu-system-x86_64 \
-chardev null,id=foo \
-device vhost-user-blk-pci,queue-size=4096,chardev=foo
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1935014
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20210413165654.50810-1-kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 68bf7336533faa6aa90fdd4558edddbf5d8ef814)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hw/block/vhost-user-blk.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 0b5b9d44cd..f5e9682703 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -467,6 +467,11 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
error_setg(errp, "vhost-user-blk: queue size must be non-zero");
return;
}
+ if (s->queue_size > VIRTQUEUE_MAX_SIZE) {
+ error_setg(errp, "vhost-user-blk: queue size must not exceed %d",
+ VIRTQUEUE_MAX_SIZE);
+ return;
+ }
if (!vhost_user_init(&s->vhost_user, &s->chardev, errp)) {
return;
--
2.27.0

View File

@ -0,0 +1,44 @@
From 28ab6c187224be79fe02fb1b5037d1c0b300a778 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 12 Jul 2021 10:22:29 -0400
Subject: [PATCH 09/43] vhost-user-blk: Get more feature flags from vhost
device
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
VIRTIO_F_RING_PACKED and VIRTIO_F_IOMMU_PLATFORM need to be supported by
the vhost device, otherwise advertising it to the guest doesn't result
in a working configuration. They are currently not supported by the
vhost-user-blk export in QEMU.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1935020
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Message-Id: <20210429171316.162022-5-kwolf@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 7556a320c98812ca6648b707393f4513387faf73)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hw/block/vhost-user-blk.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index f3a45af97c..c7e502f4c7 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -47,6 +47,8 @@ static const int user_feature_bits[] = {
VIRTIO_RING_F_INDIRECT_DESC,
VIRTIO_RING_F_EVENT_IDX,
VIRTIO_F_NOTIFY_ON_EMPTY,
+ VIRTIO_F_RING_PACKED,
+ VIRTIO_F_IOMMU_PLATFORM,
VHOST_INVALID_FEATURE_BIT
};
--
2.27.0

View File

@ -0,0 +1,120 @@
From a0fcc5faf35fb266dbe45259b79a57ba057e3144 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 12 Jul 2021 10:22:28 -0400
Subject: [PATCH 08/43] vhost-user-blk: Improve error reporting in realize
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
Now that vhost_user_blk_connect() is not called from an event handler
any more, but directly from vhost_user_blk_device_realize(), we can
actually make use of Error again instead of calling error_report() in
the inner function and setting a more generic and therefore less useful
error message in realize() itself.
With Error, the callers are responsible for adding context if necessary
(such as the "-device" option the error refers to). Additional prefixes
are redundant and better omitted.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Acked-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Message-Id: <20210429171316.162022-4-kwolf@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 5b9243d2654adc58ce472d0536a7a177b4fe0f90)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hw/block/vhost-user-blk.c | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index c0b9958da1..f3a45af97c 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -311,7 +311,7 @@ static void vhost_user_blk_reset(VirtIODevice *vdev)
vhost_dev_free_inflight(s->inflight);
}
-static int vhost_user_blk_connect(DeviceState *dev)
+static int vhost_user_blk_connect(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VHostUserBlk *s = VHOST_USER_BLK(vdev);
@@ -331,8 +331,7 @@ static int vhost_user_blk_connect(DeviceState *dev)
ret = vhost_dev_init(&s->dev, &s->vhost_user, VHOST_BACKEND_TYPE_USER, 0);
if (ret < 0) {
- error_report("vhost-user-blk: vhost initialization failed: %s",
- strerror(-ret));
+ error_setg_errno(errp, -ret, "vhost initialization failed");
return ret;
}
@@ -340,8 +339,7 @@ static int vhost_user_blk_connect(DeviceState *dev)
if (virtio_device_started(vdev, vdev->status)) {
ret = vhost_user_blk_start(vdev);
if (ret < 0) {
- error_report("vhost-user-blk: vhost start failed: %s",
- strerror(-ret));
+ error_setg_errno(errp, -ret, "vhost start failed");
return ret;
}
}
@@ -380,10 +378,12 @@ static void vhost_user_blk_event(void *opaque, QEMUChrEvent event)
DeviceState *dev = opaque;
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VHostUserBlk *s = VHOST_USER_BLK(vdev);
+ Error *local_err = NULL;
switch (event) {
case CHR_EVENT_OPENED:
- if (vhost_user_blk_connect(dev) < 0) {
+ if (vhost_user_blk_connect(dev, &local_err) < 0) {
+ error_report_err(local_err);
qemu_chr_fe_disconnect(&s->chardev);
return;
}
@@ -426,7 +426,7 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
int i, ret;
if (!s->chardev.chr) {
- error_setg(errp, "vhost-user-blk: chardev is mandatory");
+ error_setg(errp, "chardev is mandatory");
return;
}
@@ -434,16 +434,16 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
s->num_queues = 1;
}
if (!s->num_queues || s->num_queues > VIRTIO_QUEUE_MAX) {
- error_setg(errp, "vhost-user-blk: invalid number of IO queues");
+ error_setg(errp, "invalid number of IO queues");
return;
}
if (!s->queue_size) {
- error_setg(errp, "vhost-user-blk: queue size must be non-zero");
+ error_setg(errp, "queue size must be non-zero");
return;
}
if (s->queue_size > VIRTQUEUE_MAX_SIZE) {
- error_setg(errp, "vhost-user-blk: queue size must not exceed %d",
+ error_setg(errp, "queue size must not exceed %d",
VIRTQUEUE_MAX_SIZE);
return;
}
@@ -469,8 +469,7 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
goto virtio_err;
}
- if (vhost_user_blk_connect(dev) < 0) {
- error_setg(errp, "vhost-user-blk: could not connect");
+ if (vhost_user_blk_connect(dev, errp) < 0) {
qemu_chr_fe_disconnect(&s->chardev);
goto virtio_err;
}
--
2.27.0

View File

@ -0,0 +1,53 @@
From f90c21b271d88733e604b3645986f8362048b0f0 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 12 Jul 2021 10:22:26 -0400
Subject: [PATCH 06/43] vhost-user-blk: Make sure to set Error on realize
failure
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
We have to set errp before jumping to virtio_err, otherwise the caller
(virtio_device_realize()) will take this as success and crash when it
later tries to access things that we've already freed in the error path.
Fixes: 77542d431491788d1e8e79d93ce10172ef207775
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20210429171316.162022-2-kwolf@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Acked-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit f26729715ef21325f972f693607580a829ad1cbb)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hw/block/vhost-user-blk.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index f5e9682703..7c85248a7b 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -447,7 +447,6 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VHostUserBlk *s = VHOST_USER_BLK(vdev);
- Error *err = NULL;
int i, ret;
if (!s->chardev.chr) {
@@ -495,8 +494,7 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
NULL, true);
reconnect:
- if (qemu_chr_fe_wait_connected(&s->chardev, &err) < 0) {
- error_report_err(err);
+ if (qemu_chr_fe_wait_connected(&s->chardev, errp) < 0) {
goto virtio_err;
}
--
2.27.0

View File

@ -0,0 +1,53 @@
From 0834f460b52a1a6b2bc5575ff2e05458d7036257 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 12 Jul 2021 10:22:30 -0400
Subject: [PATCH 10/43] virtio: Fail if iommu_platform is requested, but
unsupported
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-Bugzilla: 1957194
Commit 2943b53f6 (' virtio: force VIRTIO_F_IOMMU_PLATFORM') made sure
that vhost can't just reject VIRTIO_F_IOMMU_PLATFORM when it was
requested. However, just adding it back to the negotiated flags isn't
right either because it promises support to the guest that the device
actually doesn't support. One example of a vhost-user device that
doesn't have support for the flag is the vhost-user-blk export of QEMU.
Instead of successfully creating a device that doesn't work, just fail
to plug the device when it doesn't support the feature, but it was
requested. This results in much clearer error messages.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1935019
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Message-Id: <20210429171316.162022-6-kwolf@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 04ceb61a4075fadbf374ef89662c41999da83489)
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hw/virtio/virtio-bus.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index d6332d45c3..859978d248 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -69,6 +69,11 @@ void virtio_bus_device_plugged(VirtIODevice *vdev, Error **errp)
return;
}
+ if (has_iommu && !virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {
+ error_setg(errp, "iommu_platform=true is not supported by the device");
+ return;
+ }
+
if (klass->device_plugged != NULL) {
klass->device_plugged(qbus->parent, &local_err);
}
--
2.27.0

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +0,0 @@
[Unit]
Description=Persistent Reservation Daemon for QEMU
[Service]
WorkingDirectory=/tmp
Type=simple
ExecStart=/usr/bin/qemu-pr-helper
PrivateTmp=yes
ProtectSystem=strict
ReadWritePaths=/var/run
RestrictAddressFamilies=AF_UNIX
Restart=always
RestartSec=0
[Install]

View File

@ -1,9 +0,0 @@
[Unit]
Description=Persistent Reservation Daemon for QEMU
[Socket]
ListenStream=/run/qemu-pr-helper.sock
SocketMode=0600
[Install]
WantedBy=multi-user.target