aa42255b5b
- Include upstream patches targeted for the next stable release (bug fixes only) spapr-Fix-failure-path-for-attempting-to.patch target-i386-do-not-set-unsupported-VMX-s.patch target-xtensa-fix-pasto-in-pfwait.r-opco.patch tcg-i386-Fix-INDEX_op_dup2_vec.patch tcg-mips-mips-sync-encode-error.patch vhost-user-gpu-Release-memory-returned-b.patch vpc-Don-t-round-up-already-aligned-BAT-s.patch xen-block-Fix-double-qlist-remove-and-re.patch - Fix bug causing weak encryption in PAuth for ARM (CVE-2020-10702 bsc#1168681) target-arm-Fix-PAuth-sbox-functions.patch - Fix OOB in tulip NIC emulation (CVE-2020-11102 bsc#1168713 net-tulip-check-frame-size-and-r-w-data-.patch - Note that previously included patch addresses CVE-2020-1711 and bsc#1166240 iscsi-Cap-block-count-from-GET-LBA-STATU.patch - Include performance improvement (and related?) patch aio-wait-delegate-polling-of-main-AioCon.patch async-use-explicit-memory-barriers.patch - Rework previous patch at Olaf H.'s direction hw-i386-disable-smbus-migration-for-xenf.patch - Eliminate is_opensuse usage in producing seabios version string what we are doing here is just replacing the upstream string with one indicating that the openSUSE build service built it, and so just leave it as "-rebuilt.opensuse.org" - Alter algorithm used to produce "unique" symbol for coordinating qemu with the optional modules it may load. This is a reasonable relaxation for broader compatibility configure-remove-pkgversion-from-CONFIG_.patch - Tweak supported.*.txt for latest deprecations, and other fixes - Tweak update_git.sh, config.sh - One more fix is needed for: s390x Protected Virtualization support - start and control guest in secure mode (bsc#1167075 jsc#SLE-7407) s390x-s390-virtio-ccw-Fix-build-on-syste.patch OBS-URL: https://build.opensuse.org/request/show/795118 OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=542
156 lines
5.4 KiB
Diff
156 lines
5.4 KiB
Diff
From: Anthony PERARD <anthony.perard@citrix.com>
|
|
Date: Mon, 6 Apr 2020 15:02:17 +0100
|
|
Subject: xen-block: Fix double qlist remove and request leak
|
|
|
|
Git-commit: 36d883ba0de8a281072ded2b51e0a711fd002139
|
|
|
|
Commit a31ca6801c02 ("qemu/queue.h: clear linked list pointers on
|
|
remove") revealed that a request was removed twice from a list, once
|
|
in xen_block_finish_request() and a second time in
|
|
xen_block_release_request() when both function are called from
|
|
xen_block_complete_aio(). But also, the `requests_inflight' counter is
|
|
decreased twice, and thus became negative.
|
|
|
|
This is a bug that was introduced in bfd0d6366043 ("xen-block: improve
|
|
response latency"), where a `finished' list was removed.
|
|
|
|
That commit also introduced a leak of request in xen_block_do_aio().
|
|
That function calls xen_block_finish_request() but the request is
|
|
never released after that.
|
|
|
|
To fix both issue, we do two changes:
|
|
- we squash finish_request() and release_request() together as we want
|
|
to remove a request from 'inflight' list to add it to 'freelist'.
|
|
- before releasing a request, we need to let the other end know the
|
|
result, thus we should call xen_block_send_response() before
|
|
releasing a request.
|
|
|
|
The first change fixes the double QLIST_REMOVE() as we remove the extra
|
|
call. The second change makes the leak go away because if we want to
|
|
call finish_request(), we need to call a function that does all of
|
|
finish, send response, and release.
|
|
|
|
Fixes: bfd0d6366043 ("xen-block: improve response latency")
|
|
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
|
|
Message-Id: <20200406140217.1441858-1-anthony.perard@citrix.com>
|
|
Reviewed-by: Paul Durrant <paul@xen.org>
|
|
[mreitz: Amended commit message as per Paul's suggestions]
|
|
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
|
---
|
|
hw/block/dataplane/xen-block.c | 48 ++++++++++++----------------------
|
|
1 file changed, 16 insertions(+), 32 deletions(-)
|
|
|
|
diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c
|
|
index 3b9caeb2fa00a1f4eb338fca7a89..c4ed2870ecd779bf40eb4f3eded3 100644
|
|
--- a/hw/block/dataplane/xen-block.c
|
|
+++ b/hw/block/dataplane/xen-block.c
|
|
@@ -64,6 +64,8 @@ struct XenBlockDataPlane {
|
|
AioContext *ctx;
|
|
};
|
|
|
|
+static int xen_block_send_response(XenBlockRequest *request);
|
|
+
|
|
static void reset_request(XenBlockRequest *request)
|
|
{
|
|
memset(&request->req, 0, sizeof(request->req));
|
|
@@ -115,23 +117,26 @@ out:
|
|
return request;
|
|
}
|
|
|
|
-static void xen_block_finish_request(XenBlockRequest *request)
|
|
+static void xen_block_complete_request(XenBlockRequest *request)
|
|
{
|
|
XenBlockDataPlane *dataplane = request->dataplane;
|
|
|
|
- QLIST_REMOVE(request, list);
|
|
- dataplane->requests_inflight--;
|
|
-}
|
|
+ if (xen_block_send_response(request)) {
|
|
+ Error *local_err = NULL;
|
|
|
|
-static void xen_block_release_request(XenBlockRequest *request)
|
|
-{
|
|
- XenBlockDataPlane *dataplane = request->dataplane;
|
|
+ xen_device_notify_event_channel(dataplane->xendev,
|
|
+ dataplane->event_channel,
|
|
+ &local_err);
|
|
+ if (local_err) {
|
|
+ error_report_err(local_err);
|
|
+ }
|
|
+ }
|
|
|
|
QLIST_REMOVE(request, list);
|
|
+ dataplane->requests_inflight--;
|
|
reset_request(request);
|
|
request->dataplane = dataplane;
|
|
QLIST_INSERT_HEAD(&dataplane->freelist, request, list);
|
|
- dataplane->requests_inflight--;
|
|
}
|
|
|
|
/*
|
|
@@ -246,7 +251,6 @@ static int xen_block_copy_request(XenBlockRequest *request)
|
|
}
|
|
|
|
static int xen_block_do_aio(XenBlockRequest *request);
|
|
-static int xen_block_send_response(XenBlockRequest *request);
|
|
|
|
static void xen_block_complete_aio(void *opaque, int ret)
|
|
{
|
|
@@ -286,7 +290,6 @@ static void xen_block_complete_aio(void *opaque, int ret)
|
|
}
|
|
|
|
request->status = request->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
|
|
- xen_block_finish_request(request);
|
|
|
|
switch (request->req.operation) {
|
|
case BLKIF_OP_WRITE:
|
|
@@ -306,17 +309,8 @@ static void xen_block_complete_aio(void *opaque, int ret)
|
|
default:
|
|
break;
|
|
}
|
|
- if (xen_block_send_response(request)) {
|
|
- Error *local_err = NULL;
|
|
|
|
- xen_device_notify_event_channel(dataplane->xendev,
|
|
- dataplane->event_channel,
|
|
- &local_err);
|
|
- if (local_err) {
|
|
- error_report_err(local_err);
|
|
- }
|
|
- }
|
|
- xen_block_release_request(request);
|
|
+ xen_block_complete_request(request);
|
|
|
|
if (dataplane->more_work) {
|
|
qemu_bh_schedule(dataplane->bh);
|
|
@@ -420,8 +414,8 @@ static int xen_block_do_aio(XenBlockRequest *request)
|
|
return 0;
|
|
|
|
err:
|
|
- xen_block_finish_request(request);
|
|
request->status = BLKIF_RSP_ERROR;
|
|
+ xen_block_complete_request(request);
|
|
return -1;
|
|
}
|
|
|
|
@@ -575,17 +569,7 @@ static bool xen_block_handle_requests(XenBlockDataPlane *dataplane)
|
|
break;
|
|
};
|
|
|
|
- if (xen_block_send_response(request)) {
|
|
- Error *local_err = NULL;
|
|
-
|
|
- xen_device_notify_event_channel(dataplane->xendev,
|
|
- dataplane->event_channel,
|
|
- &local_err);
|
|
- if (local_err) {
|
|
- error_report_err(local_err);
|
|
- }
|
|
- }
|
|
- xen_block_release_request(request);
|
|
+ xen_block_complete_request(request);
|
|
continue;
|
|
}
|
|
|