From 2bc292dedb91786197bccbe4f87856820c89e27d Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Mar 01 2022 10:43:39 +0000 Subject: import qemu-kvm-6.2.0-9.el9 --- diff --git a/SOURCES/kvm-Enable-SGX-RH-Only.patch b/SOURCES/kvm-Enable-SGX-RH-Only.patch new file mode 100644 index 0000000..63f335b --- /dev/null +++ b/SOURCES/kvm-Enable-SGX-RH-Only.patch @@ -0,0 +1,28 @@ +From f4f7c62a4658a570d3ad694b64463665fa4b80a7 Mon Sep 17 00:00:00 2001 +From: Paul Lai +Date: Fri, 21 Jan 2022 13:14:42 -0500 +Subject: [PATCH 04/12] Enable SGX -- RH Only + +RH-Author: Paul Lai +RH-MergeRequest: 65: Enable SGX and add SGX Numa support +RH-Commit: [4/5] 2cd4ee4a429f5e7b1c32e83a10bf488503603795 +RH-Bugzilla: 2033708 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Bandan Das +RH-Acked-by: Cornelia Huck +--- + configs/devices/x86_64-softmmu/x86_64-rh-devices.mak | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak +index dc03fbb671..327b1bee62 100644 +--- a/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak ++++ b/configs/devices/x86_64-softmmu/x86_64-rh-devices.mak +@@ -101,3 +101,4 @@ CONFIG_TPM=y + CONFIG_TPM_CRB=y + CONFIG_TPM_TIS_ISA=y + CONFIG_TPM_EMULATOR=y ++CONFIG_SGX=y +-- +2.27.0 + diff --git a/SOURCES/kvm-block-Lock-AioContext-for-drain_end-in-blockdev-reop.patch b/SOURCES/kvm-block-Lock-AioContext-for-drain_end-in-blockdev-reop.patch new file mode 100644 index 0000000..6fc7f38 --- /dev/null +++ b/SOURCES/kvm-block-Lock-AioContext-for-drain_end-in-blockdev-reop.patch @@ -0,0 +1,63 @@ +From 7b973b9cb7b890eaf9a31c99f5c272b513322ac1 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 3 Feb 2022 15:05:33 +0100 +Subject: [PATCH 1/8] block: Lock AioContext for drain_end in blockdev-reopen + +RH-Author: Kevin Wolf +RH-MergeRequest: 73: block: Lock AioContext for drain_end in blockdev-reopen +RH-Commit: [1/2] db25e999152b0e4f09decade1ac76b9f56cd9706 (kmwolf/centos-qemu-kvm) +RH-Bugzilla: 2046659 +RH-Acked-by: Sergio Lopez +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Reitz + +bdrv_subtree_drained_end() requires the caller to hold the AioContext +lock for the drained node. Not doing this for nodes outside of the main +AioContext leads to crashes when AIO_WAIT_WHILE() needs to wait and +tries to temporarily release the lock. + +Fixes: 3908b7a8994fa5ef7a89aa58cd5a02fc58141592 +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2046659 +Reported-by: Qing Wang +Signed-off-by: Kevin Wolf +Message-Id: <20220203140534.36522-2-kwolf@redhat.com> +Reviewed-by: Hanna Reitz +Signed-off-by: Kevin Wolf +(cherry picked from commit aba8205be0707b9d108e32254e186ba88107a869) +Signed-off-by: Kevin Wolf +--- + blockdev.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/blockdev.c b/blockdev.c +index b35072644e..565f6a81fd 100644 +--- a/blockdev.c ++++ b/blockdev.c +@@ -3562,6 +3562,7 @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp) + { + BlockReopenQueue *queue = NULL; + GSList *drained = NULL; ++ GSList *p; + + /* Add each one of the BDS that we want to reopen to the queue */ + for (; reopen_list != NULL; reopen_list = reopen_list->next) { +@@ -3611,7 +3612,15 @@ void qmp_blockdev_reopen(BlockdevOptionsList *reopen_list, Error **errp) + + fail: + bdrv_reopen_queue_free(queue); +- g_slist_free_full(drained, (GDestroyNotify) bdrv_subtree_drained_end); ++ for (p = drained; p; p = p->next) { ++ BlockDriverState *bs = p->data; ++ AioContext *ctx = bdrv_get_aio_context(bs); ++ ++ aio_context_acquire(ctx); ++ bdrv_subtree_drained_end(bs); ++ aio_context_release(ctx); ++ } ++ g_slist_free(drained); + } + + void qmp_blockdev_del(const char *node_name, Error **errp) +-- +2.27.0 + diff --git a/SOURCES/kvm-block-backend-prevent-dangling-BDS-pointers-across-a.patch b/SOURCES/kvm-block-backend-prevent-dangling-BDS-pointers-across-a.patch new file mode 100644 index 0000000..8dbf30f --- /dev/null +++ b/SOURCES/kvm-block-backend-prevent-dangling-BDS-pointers-across-a.patch @@ -0,0 +1,129 @@ +From 87f3b10dc600ac12272ee6cdc67571910ea722f6 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Tue, 11 Jan 2022 15:36:12 +0000 +Subject: [PATCH 10/12] block-backend: prevent dangling BDS pointers across + aio_poll() + +RH-Author: Hanna Reitz +RH-MergeRequest: 71: block-backend: prevent dangling BDS pointers across aio_poll() +RH-Commit: [1/2] 1b4cab39bf8c933ab910293a29bfceaa9e821068 (hreitz/qemu-kvm-c-9-s) +RH-Bugzilla: 2040123 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Emanuele Giuseppe Esposito + +The BlockBackend root child can change when aio_poll() is invoked. This +happens when a temporary filter node is removed upon blockjob +completion, for example. + +Functions in block/block-backend.c must be aware of this when using a +blk_bs() pointer across aio_poll() because the BlockDriverState refcnt +may reach 0, resulting in a stale pointer. + +One example is scsi_device_purge_requests(), which calls blk_drain() to +wait for in-flight requests to cancel. If the backup blockjob is active, +then the BlockBackend root child is a temporary filter BDS owned by the +blockjob. The blockjob can complete during bdrv_drained_begin() and the +last reference to the BDS is released when the temporary filter node is +removed. This results in a use-after-free when blk_drain() calls +bdrv_drained_end(bs) on the dangling pointer. + +Explicitly hold a reference to bs across block APIs that invoke +aio_poll(). + +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2021778 +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2036178 +Signed-off-by: Stefan Hajnoczi +Message-Id: <20220111153613.25453-2-stefanha@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 1e3552dbd28359d35967b7c28dc86cde1bc29205) +Signed-off-by: Hanna Reitz +--- + block/block-backend.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/block/block-backend.c b/block/block-backend.c +index 12ef80ea17..23e727199b 100644 +--- a/block/block-backend.c ++++ b/block/block-backend.c +@@ -822,16 +822,22 @@ BlockBackend *blk_by_public(BlockBackendPublic *public) + void blk_remove_bs(BlockBackend *blk) + { + ThrottleGroupMember *tgm = &blk->public.throttle_group_member; +- BlockDriverState *bs; + BdrvChild *root; + + notifier_list_notify(&blk->remove_bs_notifiers, blk); + if (tgm->throttle_state) { +- bs = blk_bs(blk); ++ BlockDriverState *bs = blk_bs(blk); ++ ++ /* ++ * Take a ref in case blk_bs() changes across bdrv_drained_begin(), for ++ * example, if a temporary filter node is removed by a blockjob. ++ */ ++ bdrv_ref(bs); + bdrv_drained_begin(bs); + throttle_group_detach_aio_context(tgm); + throttle_group_attach_aio_context(tgm, qemu_get_aio_context()); + bdrv_drained_end(bs); ++ bdrv_unref(bs); + } + + blk_update_root_state(blk); +@@ -1705,6 +1711,7 @@ void blk_drain(BlockBackend *blk) + BlockDriverState *bs = blk_bs(blk); + + if (bs) { ++ bdrv_ref(bs); + bdrv_drained_begin(bs); + } + +@@ -1714,6 +1721,7 @@ void blk_drain(BlockBackend *blk) + + if (bs) { + bdrv_drained_end(bs); ++ bdrv_unref(bs); + } + } + +@@ -2044,10 +2052,13 @@ static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context, + int ret; + + if (bs) { ++ bdrv_ref(bs); ++ + if (update_root_node) { + ret = bdrv_child_try_set_aio_context(bs, new_context, blk->root, + errp); + if (ret < 0) { ++ bdrv_unref(bs); + return ret; + } + } +@@ -2057,6 +2068,8 @@ static int blk_do_set_aio_context(BlockBackend *blk, AioContext *new_context, + throttle_group_attach_aio_context(tgm, new_context); + bdrv_drained_end(bs); + } ++ ++ bdrv_unref(bs); + } + + blk->ctx = new_context; +@@ -2326,11 +2339,13 @@ void blk_io_limits_disable(BlockBackend *blk) + ThrottleGroupMember *tgm = &blk->public.throttle_group_member; + assert(tgm->throttle_state); + if (bs) { ++ bdrv_ref(bs); + bdrv_drained_begin(bs); + } + throttle_group_unregister_tgm(tgm); + if (bs) { + bdrv_drained_end(bs); ++ bdrv_unref(bs); + } + } + +-- +2.27.0 + diff --git a/SOURCES/kvm-block-io-Update-BSC-only-if-want_zero-is-true.patch b/SOURCES/kvm-block-io-Update-BSC-only-if-want_zero-is-true.patch new file mode 100644 index 0000000..5fff268 --- /dev/null +++ b/SOURCES/kvm-block-io-Update-BSC-only-if-want_zero-is-true.patch @@ -0,0 +1,56 @@ +From a6b472de71f6ebbe44025e1348c90e6f1f2b2326 Mon Sep 17 00:00:00 2001 +From: Hanna Reitz +Date: Tue, 18 Jan 2022 17:59:59 +0100 +Subject: [PATCH 06/12] block/io: Update BSC only if want_zero is true + +RH-Author: Hanna Reitz +RH-MergeRequest: 69: block/io: Update BSC only if want_zero is true +RH-Commit: [1/2] ad19ff86c3420cafe5a9e785ee210e482fbc8cd7 (hreitz/qemu-kvm-c-9-s) +RH-Bugzilla: 2041461 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Kevin Wolf + +We update the block-status cache whenever we get new information from a +bdrv_co_block_status() call to the block driver. However, if we have +passed want_zero=false to that call, it may flag areas containing zeroes +as data, and so we would update the block-status cache with wrong +information. + +Therefore, we should not update the cache with want_zero=false. + +Reported-by: Nir Soffer +Fixes: 0bc329fbb00 ("block: block-status cache for data regions") +Reviewed-by: Nir Soffer +Cc: qemu-stable@nongnu.org +Signed-off-by: Hanna Reitz +Message-Id: <20220118170000.49423-2-hreitz@redhat.com> +Reviewed-by: Eric Blake +Signed-off-by: Eric Blake +(cherry picked from commit 113b727ce788335cf76f65355d670c9bc130fd75) +Signed-off-by: Hanna Reitz +--- + block/io.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/block/io.c b/block/io.c +index bb0a254def..4e4cb556c5 100644 +--- a/block/io.c ++++ b/block/io.c +@@ -2497,8 +2497,12 @@ static int coroutine_fn bdrv_co_block_status(BlockDriverState *bs, + * non-protocol nodes, and then it is never used. However, filling + * the cache requires an RCU update, so double check here to avoid + * such an update if possible. ++ * ++ * Check want_zero, because we only want to update the cache when we ++ * have accurate information about what is zero and what is data. + */ +- if (ret == (BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID) && ++ if (want_zero && ++ ret == (BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID) && + QLIST_EMPTY(&bs->children)) + { + /* +-- +2.27.0 + diff --git a/SOURCES/kvm-block-nbd-Assert-there-are-no-timers-when-closed.patch b/SOURCES/kvm-block-nbd-Assert-there-are-no-timers-when-closed.patch new file mode 100644 index 0000000..24c5b8a --- /dev/null +++ b/SOURCES/kvm-block-nbd-Assert-there-are-no-timers-when-closed.patch @@ -0,0 +1,52 @@ +From 76b03619435d0b2f0125ee7aa5c94f2b889247de Mon Sep 17 00:00:00 2001 +From: Hanna Reitz +Date: Fri, 4 Feb 2022 12:10:08 +0100 +Subject: [PATCH 4/8] block/nbd: Assert there are no timers when closed + +RH-Author: Hanna Reitz +RH-MergeRequest: 74: block/nbd: Handle AioContext changes +RH-Commit: [2/6] 56903457ca35d9c596aeb6827a48f80e8eabd66a (hreitz/qemu-kvm-c-9-s) +RH-Bugzilla: 2033626 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi + +Our two timers must not remain armed beyond nbd_clear_bdrvstate(), or +they will access freed data when they fire. + +This patch is separate from the patches that actually fix the issue +(HEAD^^ and HEAD^) so that you can run the associated regression iotest +(281) on a configuration that reproducibly exposes the bug. + +Reviewed-by: Vladimir Sementsov-Ogievskiy +Signed-off-by: Hanna Reitz +Signed-off-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 8a39c381e5e407d2fe5500324323f90a8540fa90) + +Conflict: +- block/nbd.c: open_timer was introduced after the 6.2 release (for + nbd's @open-timeout parameter), and has not been backported, so drop + the assertion that it is NULL + +Signed-off-by: Hanna Reitz +--- + block/nbd.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/block/nbd.c b/block/nbd.c +index b8e5a9b4cc..aab20125d8 100644 +--- a/block/nbd.c ++++ b/block/nbd.c +@@ -108,6 +108,9 @@ static void nbd_clear_bdrvstate(BlockDriverState *bs) + + yank_unregister_instance(BLOCKDEV_YANK_INSTANCE(bs->node_name)); + ++ /* Must not leave timers behind that would access freed data */ ++ assert(!s->reconnect_delay_timer); ++ + object_unref(OBJECT(s->tlscreds)); + qapi_free_SocketAddress(s->saddr); + s->saddr = NULL; +-- +2.27.0 + diff --git a/SOURCES/kvm-block-nbd-Delete-reconnect-delay-timer-when-done.patch b/SOURCES/kvm-block-nbd-Delete-reconnect-delay-timer-when-done.patch new file mode 100644 index 0000000..0cdf622 --- /dev/null +++ b/SOURCES/kvm-block-nbd-Delete-reconnect-delay-timer-when-done.patch @@ -0,0 +1,54 @@ +From eeb4683ad8c40a03a4e91463ec1d1b651974b744 Mon Sep 17 00:00:00 2001 +From: Hanna Reitz +Date: Fri, 4 Feb 2022 12:10:06 +0100 +Subject: [PATCH 3/8] block/nbd: Delete reconnect delay timer when done + +RH-Author: Hanna Reitz +RH-MergeRequest: 74: block/nbd: Handle AioContext changes +RH-Commit: [1/6] 34f92910b6ffd256d781109a2b39737fc6ab449c (hreitz/qemu-kvm-c-9-s) +RH-Bugzilla: 2033626 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi + +We start the reconnect delay timer to cancel the reconnection attempt +after a while. Once nbd_co_do_establish_connection() has returned, this +attempt is over, and we no longer need the timer. + +Delete it before returning from nbd_reconnect_attempt(), so that it does +not persist beyond the I/O request that was paused for reconnecting; we +do not want it to fire in a drained section, because all sort of things +can happen in such a section (e.g. the AioContext might be changed, and +we do not want the timer to fire in the wrong context; or the BDS might +even be deleted, and so the timer CB would access already-freed data). + +Reviewed-by: Vladimir Sementsov-Ogievskiy +Signed-off-by: Hanna Reitz +Signed-off-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 3ce1fc16bad9c3f8b7b10b451a224d6d76e5c551) +Signed-off-by: Hanna Reitz +--- + block/nbd.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/block/nbd.c b/block/nbd.c +index 5ef462db1b..b8e5a9b4cc 100644 +--- a/block/nbd.c ++++ b/block/nbd.c +@@ -353,6 +353,13 @@ static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s) + } + + nbd_co_do_establish_connection(s->bs, NULL); ++ ++ /* ++ * The reconnect attempt is done (maybe successfully, maybe not), so ++ * we no longer need this timer. Delete it so it will not outlive ++ * this I/O request (so draining removes all timers). ++ */ ++ reconnect_delay_timer_del(s); + } + + static coroutine_fn int nbd_receive_replies(BDRVNBDState *s, uint64_t handle) +-- +2.27.0 + diff --git a/SOURCES/kvm-block-nbd-Move-s-ioc-on-AioContext-change.patch b/SOURCES/kvm-block-nbd-Move-s-ioc-on-AioContext-change.patch new file mode 100644 index 0000000..1cb29e9 --- /dev/null +++ b/SOURCES/kvm-block-nbd-Move-s-ioc-on-AioContext-change.patch @@ -0,0 +1,107 @@ +From 6d9d86cc4e6149d4c0793e8ceb65dab7535a4561 Mon Sep 17 00:00:00 2001 +From: Hanna Reitz +Date: Fri, 4 Feb 2022 12:10:11 +0100 +Subject: [PATCH 7/8] block/nbd: Move s->ioc on AioContext change + +RH-Author: Hanna Reitz +RH-MergeRequest: 74: block/nbd: Handle AioContext changes +RH-Commit: [5/6] b3c1eb21ac70d64fdac6094468a72cfbe50a30a9 (hreitz/qemu-kvm-c-9-s) +RH-Bugzilla: 2033626 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi + +s->ioc must always be attached to the NBD node's AioContext. If that +context changes, s->ioc must be attached to the new context. + +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2033626 +Reviewed-by: Vladimir Sementsov-Ogievskiy +Signed-off-by: Hanna Reitz +Signed-off-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit e15f3a66c830e3fce99c9d56c493c2f7078a1225) + +Conflict: +- block/nbd.c: open_timer was added after the 6.2 release, so we need + not (and cannot) assert it is NULL here. + +Signed-off-by: Hanna Reitz +--- + block/nbd.c | 41 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 41 insertions(+) + +diff --git a/block/nbd.c b/block/nbd.c +index aab20125d8..a3896c7f5f 100644 +--- a/block/nbd.c ++++ b/block/nbd.c +@@ -2003,6 +2003,38 @@ static void nbd_cancel_in_flight(BlockDriverState *bs) + nbd_co_establish_connection_cancel(s->conn); + } + ++static void nbd_attach_aio_context(BlockDriverState *bs, ++ AioContext *new_context) ++{ ++ BDRVNBDState *s = bs->opaque; ++ ++ /* ++ * The reconnect_delay_timer is scheduled in I/O paths when the ++ * connection is lost, to cancel the reconnection attempt after a ++ * given time. Once this attempt is done (successfully or not), ++ * nbd_reconnect_attempt() ensures the timer is deleted before the ++ * respective I/O request is resumed. ++ * Since the AioContext can only be changed when a node is drained, ++ * the reconnect_delay_timer cannot be active here. ++ */ ++ assert(!s->reconnect_delay_timer); ++ ++ if (s->ioc) { ++ qio_channel_attach_aio_context(s->ioc, new_context); ++ } ++} ++ ++static void nbd_detach_aio_context(BlockDriverState *bs) ++{ ++ BDRVNBDState *s = bs->opaque; ++ ++ assert(!s->reconnect_delay_timer); ++ ++ if (s->ioc) { ++ qio_channel_detach_aio_context(s->ioc); ++ } ++} ++ + static BlockDriver bdrv_nbd = { + .format_name = "nbd", + .protocol_name = "nbd", +@@ -2026,6 +2058,9 @@ static BlockDriver bdrv_nbd = { + .bdrv_dirname = nbd_dirname, + .strong_runtime_opts = nbd_strong_runtime_opts, + .bdrv_cancel_in_flight = nbd_cancel_in_flight, ++ ++ .bdrv_attach_aio_context = nbd_attach_aio_context, ++ .bdrv_detach_aio_context = nbd_detach_aio_context, + }; + + static BlockDriver bdrv_nbd_tcp = { +@@ -2051,6 +2086,9 @@ static BlockDriver bdrv_nbd_tcp = { + .bdrv_dirname = nbd_dirname, + .strong_runtime_opts = nbd_strong_runtime_opts, + .bdrv_cancel_in_flight = nbd_cancel_in_flight, ++ ++ .bdrv_attach_aio_context = nbd_attach_aio_context, ++ .bdrv_detach_aio_context = nbd_detach_aio_context, + }; + + static BlockDriver bdrv_nbd_unix = { +@@ -2076,6 +2114,9 @@ static BlockDriver bdrv_nbd_unix = { + .bdrv_dirname = nbd_dirname, + .strong_runtime_opts = nbd_strong_runtime_opts, + .bdrv_cancel_in_flight = nbd_cancel_in_flight, ++ ++ .bdrv_attach_aio_context = nbd_attach_aio_context, ++ .bdrv_detach_aio_context = nbd_detach_aio_context, + }; + + static void bdrv_nbd_init(void) +-- +2.27.0 + diff --git a/SOURCES/kvm-block-nvme-fix-infinite-loop-in-nvme_free_req_queue_.patch b/SOURCES/kvm-block-nvme-fix-infinite-loop-in-nvme_free_req_queue_.patch new file mode 100644 index 0000000..bdebdc3 --- /dev/null +++ b/SOURCES/kvm-block-nvme-fix-infinite-loop-in-nvme_free_req_queue_.patch @@ -0,0 +1,71 @@ +From 6989be9d0aa08470f8b287c243dc4bf027d5fbcf Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Wed, 8 Dec 2021 15:22:46 +0000 +Subject: [PATCH 1/2] block/nvme: fix infinite loop in nvme_free_req_queue_cb() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Stefan Hajnoczi +RH-MergeRequest: 58: block/nvme: fix infinite loop in nvme_free_req_queue_cb() +RH-Commit: [1/1] 544b3f310d791a20c63b51947de0c6cbb60b0d5b (stefanha/centos-stream-qemu-kvm) +RH-Bugzilla: 2024544 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Hanna Reitz + +When the request free list is exhausted the coroutine waits on +q->free_req_queue for the next free request. Whenever a request is +completed a BH is scheduled to invoke nvme_free_req_queue_cb() and wake +up waiting coroutines. + +1. nvme_get_free_req() waits for a free request: + + while (q->free_req_head == -1) { + ... + trace_nvme_free_req_queue_wait(q->s, q->index); + qemu_co_queue_wait(&q->free_req_queue, &q->lock); + ... + } + +2. nvme_free_req_queue_cb() wakes up the coroutine: + + while (qemu_co_enter_next(&q->free_req_queue, &q->lock)) { + ^--- infinite loop when free_req_head == -1 + } + +nvme_free_req_queue_cb() and the coroutine form an infinite loop when +q->free_req_head == -1. Fix this by checking q->free_req_head in +nvme_free_req_queue_cb(). If the free request list is exhausted, don't +wake waiting coroutines. Eventually an in-flight request will complete +and the BH will be scheduled again, guaranteeing forward progress. + +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Philippe Mathieu-Daudé +Message-id: 20211208152246.244585-1-stefanha@redhat.com +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit cf4fbc3030c974fff726756a7ceef8386cdf500b) +Signed-off-by: Stefan Hajnoczi +--- + block/nvme.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/block/nvme.c b/block/nvme.c +index e4f336d79c..fa360b9b3c 100644 +--- a/block/nvme.c ++++ b/block/nvme.c +@@ -206,8 +206,9 @@ static void nvme_free_req_queue_cb(void *opaque) + NVMeQueuePair *q = opaque; + + qemu_mutex_lock(&q->lock); +- while (qemu_co_enter_next(&q->free_req_queue, &q->lock)) { +- /* Retry all pending requests */ ++ while (q->free_req_head != -1 && ++ qemu_co_enter_next(&q->free_req_queue, &q->lock)) { ++ /* Retry waiting requests */ + } + qemu_mutex_unlock(&q->lock); + } +-- +2.27.0 + diff --git a/SOURCES/kvm-block-rbd-fix-handling-of-holes-in-.bdrv_co_block_st.patch b/SOURCES/kvm-block-rbd-fix-handling-of-holes-in-.bdrv_co_block_st.patch new file mode 100644 index 0000000..39aa96c --- /dev/null +++ b/SOURCES/kvm-block-rbd-fix-handling-of-holes-in-.bdrv_co_block_st.patch @@ -0,0 +1,59 @@ +From d374d5aa4485a0c62d6b48eec64491cae2fd0873 Mon Sep 17 00:00:00 2001 +From: Peter Lieven +Date: Thu, 13 Jan 2022 15:44:25 +0100 +Subject: [PATCH 4/5] block/rbd: fix handling of holes in .bdrv_co_block_status + +RH-Author: Stefano Garzarella +RH-MergeRequest: 68: block/rbd: fix handling of holes in .bdrv_co_block_status +RH-Commit: [1/2] 8ef178b01885e3c292f7844ccff865b1a8d4faf0 (sgarzarella/qemu-kvm-c-9-s) +RH-Bugzilla: 2034791 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Kevin Wolf +RH-Acked-by: Hanna Reitz + +the assumption that we can't hit a hole if we do not diff against a snapshot was wrong. + +We can see a hole in an image if we diff against base if there exists an older snapshot +of the image and we have discarded blocks in the image where the snapshot has data. + +Fix this by simply handling a hole like an unallocated area. There are no callbacks +for unallocated areas so just bail out if we hit a hole. + +Fixes: 0347a8fd4c3faaedf119be04c197804be40a384b +Suggested-by: Ilya Dryomov +Cc: qemu-stable@nongnu.org +Signed-off-by: Peter Lieven +Message-Id: <20220113144426.4036493-2-pl@kamp.de> +Reviewed-by: Ilya Dryomov +Reviewed-by: Stefano Garzarella +Signed-off-by: Kevin Wolf +(cherry picked from commit 9e302f64bb407a9bb097b626da97228c2654cfee) +Signed-off-by: Stefano Garzarella +--- + block/rbd.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/block/rbd.c b/block/rbd.c +index def96292e0..20bb896c4a 100644 +--- a/block/rbd.c ++++ b/block/rbd.c +@@ -1279,11 +1279,11 @@ static int qemu_rbd_diff_iterate_cb(uint64_t offs, size_t len, + RBDDiffIterateReq *req = opaque; + + assert(req->offs + req->bytes <= offs); +- /* +- * we do not diff against a snapshot so we should never receive a callback +- * for a hole. +- */ +- assert(exists); ++ ++ /* treat a hole like an unallocated area and bail out */ ++ if (!exists) { ++ return 0; ++ } + + if (!req->exists && offs > req->offs) { + /* +-- +2.27.0 + diff --git a/SOURCES/kvm-block-rbd-workaround-for-ceph-issue-53784.patch b/SOURCES/kvm-block-rbd-workaround-for-ceph-issue-53784.patch new file mode 100644 index 0000000..dd3876e --- /dev/null +++ b/SOURCES/kvm-block-rbd-workaround-for-ceph-issue-53784.patch @@ -0,0 +1,103 @@ +From f035b5250529eed8d12e0b93b1b6d6f2c50003f6 Mon Sep 17 00:00:00 2001 +From: Peter Lieven +Date: Thu, 13 Jan 2022 15:44:26 +0100 +Subject: [PATCH 5/5] block/rbd: workaround for ceph issue #53784 + +RH-Author: Stefano Garzarella +RH-MergeRequest: 68: block/rbd: fix handling of holes in .bdrv_co_block_status +RH-Commit: [2/2] 5feaa2e20a77886cc1a84cdf212ade3dcda28289 (sgarzarella/qemu-kvm-c-9-s) +RH-Bugzilla: 2034791 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Kevin Wolf +RH-Acked-by: Hanna Reitz + +librbd had a bug until early 2022 that affected all versions of ceph that +supported fast-diff. This bug results in reporting of incorrect offsets +if the offset parameter to rbd_diff_iterate2 is not object aligned. + +This patch works around this bug for pre Quincy versions of librbd. + +Fixes: 0347a8fd4c3faaedf119be04c197804be40a384b +Cc: qemu-stable@nongnu.org +Signed-off-by: Peter Lieven +Message-Id: <20220113144426.4036493-3-pl@kamp.de> +Reviewed-by: Ilya Dryomov +Reviewed-by: Stefano Garzarella +Tested-by: Stefano Garzarella +Signed-off-by: Kevin Wolf +(cherry picked from commit fc176116cdea816ceb8dd969080b2b95f58edbc0) +Signed-off-by: Stefano Garzarella +--- + block/rbd.c | 42 ++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 40 insertions(+), 2 deletions(-) + +diff --git a/block/rbd.c b/block/rbd.c +index 20bb896c4a..8f183eba2a 100644 +--- a/block/rbd.c ++++ b/block/rbd.c +@@ -1320,6 +1320,7 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs, + int status, r; + RBDDiffIterateReq req = { .offs = offset }; + uint64_t features, flags; ++ uint64_t head = 0; + + assert(offset + bytes <= s->image_size); + +@@ -1347,7 +1348,43 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs, + return status; + } + +- r = rbd_diff_iterate2(s->image, NULL, offset, bytes, true, true, ++#if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 17, 0) ++ /* ++ * librbd had a bug until early 2022 that affected all versions of ceph that ++ * supported fast-diff. This bug results in reporting of incorrect offsets ++ * if the offset parameter to rbd_diff_iterate2 is not object aligned. ++ * Work around this bug by rounding down the offset to object boundaries. ++ * This is OK because we call rbd_diff_iterate2 with whole_object = true. ++ * However, this workaround only works for non cloned images with default ++ * striping. ++ * ++ * See: https://tracker.ceph.com/issues/53784 ++ */ ++ ++ /* check if RBD image has non-default striping enabled */ ++ if (features & RBD_FEATURE_STRIPINGV2) { ++ return status; ++ } ++ ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wdeprecated-declarations" ++ /* ++ * check if RBD image is a clone (= has a parent). ++ * ++ * rbd_get_parent_info is deprecated from Nautilus onwards, but the ++ * replacement rbd_get_parent is not present in Luminous and Mimic. ++ */ ++ if (rbd_get_parent_info(s->image, NULL, 0, NULL, 0, NULL, 0) != -ENOENT) { ++ return status; ++ } ++#pragma GCC diagnostic pop ++ ++ head = req.offs & (s->object_size - 1); ++ req.offs -= head; ++ bytes += head; ++#endif ++ ++ r = rbd_diff_iterate2(s->image, NULL, req.offs, bytes, true, true, + qemu_rbd_diff_iterate_cb, &req); + if (r < 0 && r != QEMU_RBD_EXIT_DIFF_ITERATE2) { + return status; +@@ -1366,7 +1403,8 @@ static int coroutine_fn qemu_rbd_co_block_status(BlockDriverState *bs, + status = BDRV_BLOCK_ZERO | BDRV_BLOCK_OFFSET_VALID; + } + +- *pnum = req.bytes; ++ assert(req.bytes > head); ++ *pnum = req.bytes - head; + return status; + } + +-- +2.27.0 + diff --git a/SOURCES/kvm-doc-Add-the-SGX-numa-description.patch b/SOURCES/kvm-doc-Add-the-SGX-numa-description.patch new file mode 100644 index 0000000..8eac5fa --- /dev/null +++ b/SOURCES/kvm-doc-Add-the-SGX-numa-description.patch @@ -0,0 +1,77 @@ +From eb88a12ab1ecfe77bcc0d0067c96fce27a3bde01 Mon Sep 17 00:00:00 2001 +From: Yang Zhong +Date: Mon, 1 Nov 2021 12:20:08 -0400 +Subject: [PATCH 03/12] doc: Add the SGX numa description + +RH-Author: Paul Lai +RH-MergeRequest: 65: Enable SGX and add SGX Numa support +RH-Commit: [3/5] c27b3f6976cbe92cc3c0e1dab0191cdd25de596a +RH-Bugzilla: 2033708 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Bandan Das +RH-Acked-by: Cornelia Huck + +Add the SGX numa reference command and how to check if +SGX numa is support or not with multiple EPC sections. + +Signed-off-by: Yang Zhong +Message-Id: <20211101162009.62161-5-yang.zhong@intel.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit d1889b36098c79e2e6ac90faf3d0dc5ec0057677) +Signed-off-by: Paul Lai +--- + docs/system/i386/sgx.rst | 31 +++++++++++++++++++++++++++---- + 1 file changed, 27 insertions(+), 4 deletions(-) + +diff --git a/docs/system/i386/sgx.rst b/docs/system/i386/sgx.rst +index f8fade5ac2..0f0a73f758 100644 +--- a/docs/system/i386/sgx.rst ++++ b/docs/system/i386/sgx.rst +@@ -141,8 +141,7 @@ To launch a SGX guest: + |qemu_system_x86| \\ + -cpu host,+sgx-provisionkey \\ + -object memory-backend-epc,id=mem1,size=64M,prealloc=on \\ +- -object memory-backend-epc,id=mem2,size=28M \\ +- -M sgx-epc.0.memdev=mem1,sgx-epc.1.memdev=mem2 ++ -M sgx-epc.0.memdev=mem1,sgx-epc.0.node=0 + + Utilizing SGX in the guest requires a kernel/OS with SGX support. + The support can be determined in guest by:: +@@ -152,8 +151,32 @@ The support can be determined in guest by:: + and SGX epc info by:: + + $ dmesg | grep sgx +- [ 1.242142] sgx: EPC section 0x180000000-0x181bfffff +- [ 1.242319] sgx: EPC section 0x181c00000-0x1837fffff ++ [ 0.182807] sgx: EPC section 0x140000000-0x143ffffff ++ [ 0.183695] sgx: [Firmware Bug]: Unable to map EPC section to online node. Fallback to the NUMA node 0. ++ ++To launch a SGX numa guest: ++ ++.. parsed-literal:: ++ ++ |qemu_system_x86| \\ ++ -cpu host,+sgx-provisionkey \\ ++ -object memory-backend-ram,size=2G,host-nodes=0,policy=bind,id=node0 \\ ++ -object memory-backend-epc,id=mem0,size=64M,prealloc=on,host-nodes=0,policy=bind \\ ++ -numa node,nodeid=0,cpus=0-1,memdev=node0 \\ ++ -object memory-backend-ram,size=2G,host-nodes=1,policy=bind,id=node1 \\ ++ -object memory-backend-epc,id=mem1,size=28M,prealloc=on,host-nodes=1,policy=bind \\ ++ -numa node,nodeid=1,cpus=2-3,memdev=node1 \\ ++ -M sgx-epc.0.memdev=mem0,sgx-epc.0.node=0,sgx-epc.1.memdev=mem1,sgx-epc.1.node=1 ++ ++and SGX epc numa info by:: ++ ++ $ dmesg | grep sgx ++ [ 0.369937] sgx: EPC section 0x180000000-0x183ffffff ++ [ 0.370259] sgx: EPC section 0x184000000-0x185bfffff ++ ++ $ dmesg | grep SRAT ++ [ 0.009981] ACPI: SRAT: Node 0 PXM 0 [mem 0x180000000-0x183ffffff] ++ [ 0.009982] ACPI: SRAT: Node 1 PXM 1 [mem 0x184000000-0x185bfffff] + + References + ---------- +-- +2.27.0 + diff --git a/SOURCES/kvm-hw-arm-smmuv3-Fix-device-reset.patch b/SOURCES/kvm-hw-arm-smmuv3-Fix-device-reset.patch new file mode 100644 index 0000000..3b8f307 --- /dev/null +++ b/SOURCES/kvm-hw-arm-smmuv3-Fix-device-reset.patch @@ -0,0 +1,61 @@ +From c08c3fbb2bb8494738fd34ec8fc9dc434ce82f4b Mon Sep 17 00:00:00 2001 +From: Eric Auger +Date: Wed, 2 Feb 2022 12:16:02 +0100 +Subject: [PATCH 12/12] hw/arm/smmuv3: Fix device reset + +RH-Author: Eric Auger +RH-MergeRequest: 72: hw/arm/smmuv3: Fix device reset +RH-Commit: [1/1] 2cfee2f7a03692681224fed96bb4f28406bf460a (eauger1/centos-qemu-kvm) +RH-Bugzilla: 2042481 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Peter Xu +RH-Acked-by: Andrew Jones + +branch: c9s +Brew: 42958737 +Upstream: yes + +We currently miss a bunch of register resets in the device reset +function. This sometimes prevents the guest from rebooting after +a system_reset (with virtio-blk-pci). For instance, we may get +the following errors: + +invalid STE +smmuv3-iommu-memory-region-0-0 translation failed for iova=0x13a9d2000(SMMU_EVT_C_BAD_STE) +Invalid read at addr 0x13A9D2000, size 2, region '(null)', reason: rejected +invalid STE +smmuv3-iommu-memory-region-0-0 translation failed for iova=0x13a9d2000(SMMU_EVT_C_BAD_STE) +Invalid write at addr 0x13A9D2000, size 2, region '(null)', reason: rejected +invalid STE + +Signed-off-by: Eric Auger +Message-id: 20220202111602.627429-1-eric.auger@redhat.com +Fixes: 10a83cb988 ("hw/arm/smmuv3: Skeleton") +Reviewed-by: Peter Maydell +Signed-off-by: Peter Maydell +(cherry picked from commit 43530095e18fd16dcd51a4b385ad2a22c36f5698) +Signed-off-by: Eric Auger +--- + hw/arm/smmuv3.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c +index 01b60bee49..1b5640bb98 100644 +--- a/hw/arm/smmuv3.c ++++ b/hw/arm/smmuv3.c +@@ -276,6 +276,12 @@ static void smmuv3_init_regs(SMMUv3State *s) + s->features = 0; + s->sid_split = 0; + s->aidr = 0x1; ++ s->cr[0] = 0; ++ s->cr0ack = 0; ++ s->irq_ctrl = 0; ++ s->gerror = 0; ++ s->gerrorn = 0; ++ s->statusr = 0; + } + + static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf, +-- +2.27.0 + diff --git a/SOURCES/kvm-iotests-281-Let-NBD-connection-yield-in-iothread.patch b/SOURCES/kvm-iotests-281-Let-NBD-connection-yield-in-iothread.patch new file mode 100644 index 0000000..20bc3a5 --- /dev/null +++ b/SOURCES/kvm-iotests-281-Let-NBD-connection-yield-in-iothread.patch @@ -0,0 +1,108 @@ +From 06583ce33fab2976157461ac4503d6f8eeb59e75 Mon Sep 17 00:00:00 2001 +From: Hanna Reitz +Date: Fri, 4 Feb 2022 12:10:12 +0100 +Subject: [PATCH 8/8] iotests/281: Let NBD connection yield in iothread + +RH-Author: Hanna Reitz +RH-MergeRequest: 74: block/nbd: Handle AioContext changes +RH-Commit: [6/6] 632b9ef5177a80d1c0c00121e1acc37272076d3e (hreitz/qemu-kvm-c-9-s) +RH-Bugzilla: 2033626 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi + +Put an NBD block device into an I/O thread, and then read data from it, +hoping that the NBD connection will yield during that read. When it +does, the coroutine must be reentered in the block device's I/O thread, +which will only happen if the NBD block driver attaches the connection's +QIOChannel to the new AioContext. It did not do that after 4ddb5d2fde +("block/nbd: drop connection_co") and prior to "block/nbd: Move s->ioc +on AioContext change", which would cause an assertion failure. + +To improve our chances of yielding, the NBD server is throttled to +reading 64 kB/s, and the NBD client reads 128 kB, so it should yield at +some point. + +Reviewed-by: Vladimir Sementsov-Ogievskiy +Signed-off-by: Hanna Reitz +Signed-off-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 8cfbe929e8c26050f0a4580a1606a370a947d4ce) +Signed-off-by: Hanna Reitz +--- + tests/qemu-iotests/281 | 28 +++++++++++++++++++++++++--- + tests/qemu-iotests/281.out | 4 ++-- + 2 files changed, 27 insertions(+), 5 deletions(-) + +diff --git a/tests/qemu-iotests/281 b/tests/qemu-iotests/281 +index 13c588be75..b2ead7f388 100755 +--- a/tests/qemu-iotests/281 ++++ b/tests/qemu-iotests/281 +@@ -253,8 +253,9 @@ class TestYieldingAndTimers(iotests.QMPTestCase): + self.create_nbd_export() + + # Simple VM with an NBD block device connected to the NBD export +- # provided by the QSD ++ # provided by the QSD, and an (initially unused) iothread + self.vm = iotests.VM() ++ self.vm.add_object('iothread,id=iothr') + self.vm.add_blockdev('nbd,node-name=nbd,server.type=unix,' + + f'server.path={self.sock},export=exp,' + + 'reconnect-delay=1') +@@ -293,19 +294,40 @@ class TestYieldingAndTimers(iotests.QMPTestCase): + # thus not see the error, and so the test will pass.) + time.sleep(2) + ++ def test_yield_in_iothread(self): ++ # Move the NBD node to the I/O thread; the NBD block driver should ++ # attach the connection's QIOChannel to that thread's AioContext, too ++ result = self.vm.qmp('x-blockdev-set-iothread', ++ node_name='nbd', iothread='iothr') ++ self.assert_qmp(result, 'return', {}) ++ ++ # Do some I/O that will be throttled by the QSD, so that the network ++ # connection hopefully will yield here. When it is resumed, it must ++ # then be resumed in the I/O thread's AioContext. ++ result = self.vm.qmp('human-monitor-command', ++ command_line='qemu-io nbd "read 0 128K"') ++ self.assert_qmp(result, 'return', '') ++ + def create_nbd_export(self): + assert self.qsd is None + +- # Simple NBD export of a null-co BDS ++ # Export a throttled null-co BDS: Reads are throttled (max 64 kB/s), ++ # writes are not. + self.qsd = QemuStorageDaemon( ++ '--object', ++ 'throttle-group,id=thrgr,x-bps-read=65536,x-bps-read-max=65536', ++ + '--blockdev', + 'null-co,node-name=null,read-zeroes=true', + ++ '--blockdev', ++ 'throttle,node-name=thr,file=null,throttle-group=thrgr', ++ + '--nbd-server', + f'addr.type=unix,addr.path={self.sock}', + + '--export', +- 'nbd,id=exp,node-name=null,name=exp,writable=true' ++ 'nbd,id=exp,node-name=thr,name=exp,writable=true' + ) + + def stop_nbd_export(self): +diff --git a/tests/qemu-iotests/281.out b/tests/qemu-iotests/281.out +index 914e3737bd..3f8a935a08 100644 +--- a/tests/qemu-iotests/281.out ++++ b/tests/qemu-iotests/281.out +@@ -1,5 +1,5 @@ +-..... ++...... + ---------------------------------------------------------------------- +-Ran 5 tests ++Ran 6 tests + + OK +-- +2.27.0 + diff --git a/SOURCES/kvm-iotests-281-Test-lingering-timers.patch b/SOURCES/kvm-iotests-281-Test-lingering-timers.patch new file mode 100644 index 0000000..7175a31 --- /dev/null +++ b/SOURCES/kvm-iotests-281-Test-lingering-timers.patch @@ -0,0 +1,174 @@ +From 3d2d7a46713d362d2ff5137841e689593da976a3 Mon Sep 17 00:00:00 2001 +From: Hanna Reitz +Date: Fri, 4 Feb 2022 12:10:10 +0100 +Subject: [PATCH 6/8] iotests/281: Test lingering timers + +RH-Author: Hanna Reitz +RH-MergeRequest: 74: block/nbd: Handle AioContext changes +RH-Commit: [4/6] d228ba3fcdfaab2d54dd5b023688a1c055cce2c2 (hreitz/qemu-kvm-c-9-s) +RH-Bugzilla: 2033626 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi + +Prior to "block/nbd: Delete reconnect delay timer when done" and +"block/nbd: Delete open timer when done", both of those timers would +remain scheduled even after successfully (re-)connecting to the server, +and they would not even be deleted when the BDS is deleted. + +This test constructs exactly this situation: +(1) Configure an @open-timeout, so the open timer is armed, and +(2) Configure a @reconnect-delay and trigger a reconnect situation + (which succeeds immediately), so the reconnect delay timer is armed. +Then we immediately delete the BDS, and sleep for longer than the +@open-timeout and @reconnect-delay. Prior to said patches, this caused +one (or both) of the timer CBs to access already-freed data. + +Accessing freed data may or may not crash, so this test can produce +false successes, but I do not know how to show the problem in a better +or more reliable way. If you run this test on "block/nbd: Assert there +are no timers when closed" and without the fix patches mentioned above, +you should reliably see an assertion failure. +(But all other tests that use the reconnect delay timer (264 and 277) +will fail in that configuration, too; as will nbd-reconnect-on-open, +which uses the open timer.) + +Remove this test from the quick group because of the two second sleep +this patch introduces. + +(I decided to put this test case into 281, because the main bug this +series addresses is in the interaction of the NBD block driver and I/O +threads, which is precisely the scope of 281. The test case for that +other bug will also be put into the test class added here. + +Also, excuse the test class's name, I couldn't come up with anything +better. The "yield" part will make sense two patches from now.) + +Reviewed-by: Vladimir Sementsov-Ogievskiy +Signed-off-by: Hanna Reitz +Signed-off-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit eaf1e85d4ddefdbd197f393fa9c5acc7ba8133b0) + +Conflict: +- @open-timeout was introduced after the 6.2 release, and has not been + backported. Consequently, there is no open_timer, and we can (and + must) drop the respective parts of the test here. + +Signed-off-by: Hanna Reitz +--- + tests/qemu-iotests/281 | 73 ++++++++++++++++++++++++++++++++++++-- + tests/qemu-iotests/281.out | 4 +-- + 2 files changed, 73 insertions(+), 4 deletions(-) + +diff --git a/tests/qemu-iotests/281 b/tests/qemu-iotests/281 +index 956698083f..13c588be75 100755 +--- a/tests/qemu-iotests/281 ++++ b/tests/qemu-iotests/281 +@@ -1,5 +1,5 @@ + #!/usr/bin/env python3 +-# group: rw quick ++# group: rw + # + # Test cases for blockdev + IOThread interactions + # +@@ -20,8 +20,9 @@ + # + + import os ++import time + import iotests +-from iotests import qemu_img ++from iotests import qemu_img, QemuStorageDaemon + + image_len = 64 * 1024 * 1024 + +@@ -243,6 +244,74 @@ class TestBlockdevBackupAbort(iotests.QMPTestCase): + # Hangs on failure, we expect this error. + self.assert_qmp(result, 'error/class', 'GenericError') + ++# Test for RHBZ#2033626 ++class TestYieldingAndTimers(iotests.QMPTestCase): ++ sock = os.path.join(iotests.sock_dir, 'nbd.sock') ++ qsd = None ++ ++ def setUp(self): ++ self.create_nbd_export() ++ ++ # Simple VM with an NBD block device connected to the NBD export ++ # provided by the QSD ++ self.vm = iotests.VM() ++ self.vm.add_blockdev('nbd,node-name=nbd,server.type=unix,' + ++ f'server.path={self.sock},export=exp,' + ++ 'reconnect-delay=1') ++ ++ self.vm.launch() ++ ++ def tearDown(self): ++ self.stop_nbd_export() ++ self.vm.shutdown() ++ ++ def test_timers_with_blockdev_del(self): ++ # Stop and restart the NBD server, and do some I/O on the client to ++ # trigger a reconnect and start the reconnect delay timer ++ self.stop_nbd_export() ++ self.create_nbd_export() ++ ++ result = self.vm.qmp('human-monitor-command', ++ command_line='qemu-io nbd "write 0 512"') ++ self.assert_qmp(result, 'return', '') ++ ++ # Reconnect is done, so the reconnect delay timer should be gone. ++ # (But there used to be a bug where it remained active, for which this ++ # is a regression test.) ++ ++ # Delete the BDS to see whether the timer is gone. If it is not, ++ # it will remain active, fire later, and then access freed data. ++ # (Or, with "block/nbd: Assert there are no timers when closed" ++ # applied, the assertion added in that patch will fail.) ++ result = self.vm.qmp('blockdev-del', node_name='nbd') ++ self.assert_qmp(result, 'return', {}) ++ ++ # Give the timer some time to fire (it has a timeout of 1 s). ++ # (Sleeping in an iotest may ring some alarm bells, but note that if ++ # the timing is off here, the test will just always pass. If we kill ++ # the VM too early, then we just kill the timer before it can fire, ++ # thus not see the error, and so the test will pass.) ++ time.sleep(2) ++ ++ def create_nbd_export(self): ++ assert self.qsd is None ++ ++ # Simple NBD export of a null-co BDS ++ self.qsd = QemuStorageDaemon( ++ '--blockdev', ++ 'null-co,node-name=null,read-zeroes=true', ++ ++ '--nbd-server', ++ f'addr.type=unix,addr.path={self.sock}', ++ ++ '--export', ++ 'nbd,id=exp,node-name=null,name=exp,writable=true' ++ ) ++ ++ def stop_nbd_export(self): ++ self.qsd.stop() ++ self.qsd = None ++ + if __name__ == '__main__': + iotests.main(supported_fmts=['qcow2'], + supported_protocols=['file']) +diff --git a/tests/qemu-iotests/281.out b/tests/qemu-iotests/281.out +index 89968f35d7..914e3737bd 100644 +--- a/tests/qemu-iotests/281.out ++++ b/tests/qemu-iotests/281.out +@@ -1,5 +1,5 @@ +-.... ++..... + ---------------------------------------------------------------------- +-Ran 4 tests ++Ran 5 tests + + OK +-- +2.27.0 + diff --git a/SOURCES/kvm-iotests-Test-blockdev-reopen-with-iothreads-and-thro.patch b/SOURCES/kvm-iotests-Test-blockdev-reopen-with-iothreads-and-thro.patch new file mode 100644 index 0000000..8616f1c --- /dev/null +++ b/SOURCES/kvm-iotests-Test-blockdev-reopen-with-iothreads-and-thro.patch @@ -0,0 +1,106 @@ +From 37593348e7d95580fb2b0009dcb026c07367f1f8 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 3 Feb 2022 15:05:34 +0100 +Subject: [PATCH 2/8] iotests: Test blockdev-reopen with iothreads and + throttling + +RH-Author: Kevin Wolf +RH-MergeRequest: 73: block: Lock AioContext for drain_end in blockdev-reopen +RH-Commit: [2/2] d19d5fa9efa4813ece75708436891041754ab910 (kmwolf/centos-qemu-kvm) +RH-Bugzilla: 2046659 +RH-Acked-by: Sergio Lopez +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Reitz + +The 'throttle' block driver implements .bdrv_co_drain_end, so +blockdev-reopen will have to wait for it to complete in the polling +loop at the end of qmp_blockdev_reopen(). This makes AIO_WAIT_WHILE() +release the AioContext lock, which causes a crash if the lock hasn't +correctly been taken. + +Signed-off-by: Kevin Wolf +Message-Id: <20220203140534.36522-3-kwolf@redhat.com> +Reviewed-by: Hanna Reitz +Signed-off-by: Kevin Wolf +(cherry picked from commit ee810602376125ca0e0afd6b7c715e13740978ea) +Signed-off-by: Kevin Wolf +--- + tests/qemu-iotests/245 | 36 +++++++++++++++++++++++++++++++++--- + tests/qemu-iotests/245.out | 4 ++-- + 2 files changed, 35 insertions(+), 5 deletions(-) + +diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245 +index 24ac43f70e..8cbed7821b 100755 +--- a/tests/qemu-iotests/245 ++++ b/tests/qemu-iotests/245 +@@ -1138,12 +1138,13 @@ class TestBlockdevReopen(iotests.QMPTestCase): + self.assertEqual(self.get_node('hd1'), None) + self.assert_qmp(self.get_node('hd2'), 'ro', True) + +- def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None): +- opts = hd_opts(0) ++ def run_test_iothreads(self, iothread_a, iothread_b, errmsg = None, ++ opts_a = None, opts_b = None): ++ opts = opts_a or hd_opts(0) + result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) + self.assert_qmp(result, 'return', {}) + +- opts2 = hd_opts(2) ++ opts2 = opts_b or hd_opts(2) + result = self.vm.qmp('blockdev-add', conv_keys = False, **opts2) + self.assert_qmp(result, 'return', {}) + +@@ -1194,6 +1195,35 @@ class TestBlockdevReopen(iotests.QMPTestCase): + def test_iothreads_switch_overlay(self): + self.run_test_iothreads('', 'iothread0') + ++ def test_iothreads_with_throttling(self): ++ # Create a throttle-group object ++ opts = { 'qom-type': 'throttle-group', 'id': 'group0', ++ 'limits': { 'iops-total': 1000 } } ++ result = self.vm.qmp('object-add', conv_keys = False, **opts) ++ self.assert_qmp(result, 'return', {}) ++ ++ # Options with a throttle filter between format and protocol ++ opts = [ ++ { ++ 'driver': iotests.imgfmt, ++ 'node-name': f'hd{idx}', ++ 'file' : { ++ 'node-name': f'hd{idx}-throttle', ++ 'driver': 'throttle', ++ 'throttle-group': 'group0', ++ 'file': { ++ 'driver': 'file', ++ 'node-name': f'hd{idx}-file', ++ 'filename': hd_path[idx], ++ }, ++ }, ++ } ++ for idx in (0, 2) ++ ] ++ ++ self.run_test_iothreads('iothread0', 'iothread0', None, ++ opts[0], opts[1]) ++ + if __name__ == '__main__': + iotests.activate_logging() + iotests.main(supported_fmts=["qcow2"], +diff --git a/tests/qemu-iotests/245.out b/tests/qemu-iotests/245.out +index 4eced19294..a4e04a3266 100644 +--- a/tests/qemu-iotests/245.out ++++ b/tests/qemu-iotests/245.out +@@ -17,8 +17,8 @@ read 1/1 bytes at offset 262152 + read 1/1 bytes at offset 262160 + 1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +-............... ++................ + ---------------------------------------------------------------------- +-Ran 25 tests ++Ran 26 tests + + OK +-- +2.27.0 + diff --git a/SOURCES/kvm-iotests-Test-qemu-img-convert-of-zeroed-data-cluster.patch b/SOURCES/kvm-iotests-Test-qemu-img-convert-of-zeroed-data-cluster.patch new file mode 100644 index 0000000..0ab3bcc --- /dev/null +++ b/SOURCES/kvm-iotests-Test-qemu-img-convert-of-zeroed-data-cluster.patch @@ -0,0 +1,81 @@ +From 51f691acd8042351d005873996d7bf4c7b045508 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Fri, 17 Dec 2021 17:46:53 +0100 +Subject: [PATCH 08/12] iotests: Test qemu-img convert of zeroed data cluster + +RH-Author: Kevin Wolf +RH-MergeRequest: 70: qemu-img convert: Fix sparseness of output image +RH-Commit: [1/2] 0770582c553ac6b0f18c035f9a0238599d4763cc (kmwolf/centos-qemu-kvm) +RH-Bugzilla: 1882917 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Reitz + +This demonstrates what happens when the block status changes in +sub-min_sparse granularity, but all of the parts are zeroed out. The +alignment logic in is_allocated_sectors() prevents that the target image +remains fully sparse as expected, but turns it into a data cluster of +explicit zeros. + +Signed-off-by: Kevin Wolf +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20211217164654.1184218-2-vsementsov@virtuozzo.com> +Tested-by: Peter Lieven +Signed-off-by: Kevin Wolf +(cherry picked from commit 51cd8bddd63540514d44808f7920811439baa253) +Signed-off-by: Kevin Wolf +--- + tests/qemu-iotests/122 | 1 + + tests/qemu-iotests/122.out | 10 ++++++++-- + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/tests/qemu-iotests/122 b/tests/qemu-iotests/122 +index efb260d822..be0f6b79e5 100755 +--- a/tests/qemu-iotests/122 ++++ b/tests/qemu-iotests/122 +@@ -251,6 +251,7 @@ $QEMU_IO -c "write -P 0 0 64k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_test + $QEMU_IO -c "write 0 1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir + $QEMU_IO -c "write 8k 1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir + $QEMU_IO -c "write 17k 1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir ++$QEMU_IO -c "write -P 0 65k 1k" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir + + for min_sparse in 4k 8k; do + echo +diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out +index 8fbdac2b39..69b8e8b803 100644 +--- a/tests/qemu-iotests/122.out ++++ b/tests/qemu-iotests/122.out +@@ -192,6 +192,8 @@ wrote 1024/1024 bytes at offset 8192 + 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + wrote 1024/1024 bytes at offset 17408 + 1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) ++wrote 1024/1024 bytes at offset 66560 ++1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + + convert -S 4k + [{ "start": 0, "length": 4096, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}, +@@ -199,7 +201,9 @@ convert -S 4k + { "start": 8192, "length": 4096, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}, + { "start": 12288, "length": 4096, "depth": 0, "present": false, "zero": true, "data": false}, + { "start": 16384, "length": 4096, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}, +-{ "start": 20480, "length": 67088384, "depth": 0, "present": false, "zero": true, "data": false}] ++{ "start": 20480, "length": 46080, "depth": 0, "present": false, "zero": true, "data": false}, ++{ "start": 66560, "length": 1024, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}, ++{ "start": 67584, "length": 67041280, "depth": 0, "present": false, "zero": true, "data": false}] + + convert -c -S 4k + [{ "start": 0, "length": 1024, "depth": 0, "present": true, "zero": false, "data": true}, +@@ -211,7 +215,9 @@ convert -c -S 4k + + convert -S 8k + [{ "start": 0, "length": 24576, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}, +-{ "start": 24576, "length": 67084288, "depth": 0, "present": false, "zero": true, "data": false}] ++{ "start": 24576, "length": 41984, "depth": 0, "present": false, "zero": true, "data": false}, ++{ "start": 66560, "length": 1024, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}, ++{ "start": 67584, "length": 67041280, "depth": 0, "present": false, "zero": true, "data": false}] + + convert -c -S 8k + [{ "start": 0, "length": 1024, "depth": 0, "present": true, "zero": false, "data": true}, +-- +2.27.0 + diff --git a/SOURCES/kvm-iotests-block-status-cache-New-test.patch b/SOURCES/kvm-iotests-block-status-cache-New-test.patch new file mode 100644 index 0000000..cd9a198 --- /dev/null +++ b/SOURCES/kvm-iotests-block-status-cache-New-test.patch @@ -0,0 +1,197 @@ +From 89fe89491f89a7526ba864a9d94d3de930261d69 Mon Sep 17 00:00:00 2001 +From: Hanna Reitz +Date: Tue, 18 Jan 2022 18:00:00 +0100 +Subject: [PATCH 07/12] iotests/block-status-cache: New test + +RH-Author: Hanna Reitz +RH-MergeRequest: 69: block/io: Update BSC only if want_zero is true +RH-Commit: [2/2] 3c5a55aca1ac7a71c175a124d63bcf7a4430a022 (hreitz/qemu-kvm-c-9-s) +RH-Bugzilla: 2041461 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Kevin Wolf + +Add a new test to verify that want_zero=false block-status calls do not +pollute the block-status cache for want_zero=true calls. + +We check want_zero=true calls and their results using `qemu-img map` +(over NBD), and want_zero=false calls also using `qemu-img map` over +NBD, but using the qemu:allocation-depth context. + +(This test case cannot be integrated into nbd-qemu-allocation, because +that is a qcow2 test, and this is a raw test.) + +Signed-off-by: Hanna Reitz +Message-Id: <20220118170000.49423-3-hreitz@redhat.com> +Reviewed-by: Nir Soffer +Reviewed-by: Eric Blake +Tested-by: Eric Blake +Signed-off-by: Eric Blake +(cherry picked from commit 6384dd534d742123d26c008d9794b20bc41359d5) +Signed-off-by: Hanna Reitz +--- + tests/qemu-iotests/tests/block-status-cache | 139 ++++++++++++++++++ + .../qemu-iotests/tests/block-status-cache.out | 5 + + 2 files changed, 144 insertions(+) + create mode 100755 tests/qemu-iotests/tests/block-status-cache + create mode 100644 tests/qemu-iotests/tests/block-status-cache.out + +diff --git a/tests/qemu-iotests/tests/block-status-cache b/tests/qemu-iotests/tests/block-status-cache +new file mode 100755 +index 0000000000..6fa10bb8f8 +--- /dev/null ++++ b/tests/qemu-iotests/tests/block-status-cache +@@ -0,0 +1,139 @@ ++#!/usr/bin/env python3 ++# group: rw quick ++# ++# Test cases for the block-status cache. ++# ++# Copyright (C) 2022 Red Hat, Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++ ++import os ++import signal ++import iotests ++from iotests import qemu_img_create, qemu_img_pipe, qemu_nbd ++ ++ ++image_size = 1 * 1024 * 1024 ++test_img = os.path.join(iotests.test_dir, 'test.img') ++ ++nbd_pidfile = os.path.join(iotests.test_dir, 'nbd.pid') ++nbd_sock = os.path.join(iotests.sock_dir, 'nbd.sock') ++ ++ ++class TestBscWithNbd(iotests.QMPTestCase): ++ def setUp(self) -> None: ++ """Just create an empty image with a read-only NBD server on it""" ++ assert qemu_img_create('-f', iotests.imgfmt, test_img, ++ str(image_size)) == 0 ++ ++ # Pass --allocation-depth to enable the qemu:allocation-depth context, ++ # which we are going to query to provoke a block-status inquiry with ++ # want_zero=false. ++ assert qemu_nbd(f'--socket={nbd_sock}', ++ f'--format={iotests.imgfmt}', ++ '--persistent', ++ '--allocation-depth', ++ '--read-only', ++ f'--pid-file={nbd_pidfile}', ++ test_img) \ ++ == 0 ++ ++ def tearDown(self) -> None: ++ with open(nbd_pidfile, encoding='utf-8') as f: ++ pid = int(f.read()) ++ os.kill(pid, signal.SIGTERM) ++ os.remove(nbd_pidfile) ++ os.remove(test_img) ++ ++ def test_with_zero_bug(self) -> None: ++ """ ++ Verify that the block-status cache is not corrupted by a ++ want_zero=false call. ++ We can provoke a want_zero=false call with `qemu-img map` over NBD with ++ x-dirty-bitmap=qemu:allocation-depth, so we first run a normal `map` ++ (which results in want_zero=true), then using said ++ qemu:allocation-depth context, and finally another normal `map` to ++ verify that the cache has not been corrupted. ++ """ ++ ++ nbd_img_opts = f'driver=nbd,server.type=unix,server.path={nbd_sock}' ++ nbd_img_opts_alloc_depth = nbd_img_opts + \ ++ ',x-dirty-bitmap=qemu:allocation-depth' ++ ++ # Normal map, results in want_zero=true. ++ # This will probably detect an allocated data sector first (qemu likes ++ # to allocate the first sector to facilitate alignment probing), and ++ # then the rest to be zero. The BSC will thus contain (if anything) ++ # one range covering the first sector. ++ map_pre = qemu_img_pipe('map', '--output=json', '--image-opts', ++ nbd_img_opts) ++ ++ # qemu:allocation-depth maps for want_zero=false. ++ # want_zero=false should (with the file driver, which the server is ++ # using) report everything as data. While this is sufficient for ++ # want_zero=false, this is nothing that should end up in the ++ # block-status cache. ++ # Due to a bug, this information did end up in the cache, though, and ++ # this would lead to wrong information being returned on subsequent ++ # want_zero=true calls. ++ # ++ # We need to run this map twice: On the first call, we probably still ++ # have the first sector in the cache, and so this will be served from ++ # the cache; and only the subsequent range will be queried from the ++ # block driver. This subsequent range will then be entered into the ++ # cache. ++ # If we did a want_zero=true call at this point, we would thus get ++ # correct information: The first sector is not covered by the cache, so ++ # we would get fresh block-status information from the driver, which ++ # would return a data range, and this would then go into the cache, ++ # evicting the wrong range from the want_zero=false call before. ++ # ++ # Therefore, we need a second want_zero=false map to reproduce: ++ # Since the first sector is not in the cache, the query for its status ++ # will go to the driver, which will return a result that reports the ++ # whole image to be a single data area. This result will then go into ++ # the cache, and so the cache will then report the whole image to ++ # contain data. ++ # ++ # Note that once the cache reports the whole image to contain data, any ++ # subsequent map operation will be served from the cache, and so we can ++ # never loop too many times here. ++ for _ in range(2): ++ # (Ignore the result, this is just to contaminate the cache) ++ qemu_img_pipe('map', '--output=json', '--image-opts', ++ nbd_img_opts_alloc_depth) ++ ++ # Now let's see whether the cache reports everything as data, or ++ # whether we get correct information (i.e. the same as we got on our ++ # first attempt). ++ map_post = qemu_img_pipe('map', '--output=json', '--image-opts', ++ nbd_img_opts) ++ ++ if map_pre != map_post: ++ print('ERROR: Map information differs before and after querying ' + ++ 'qemu:allocation-depth') ++ print('Before:') ++ print(map_pre) ++ print('After:') ++ print(map_post) ++ ++ self.fail("Map information differs") ++ ++ ++if __name__ == '__main__': ++ # The block-status cache only works on the protocol layer, so to test it, ++ # we can only use the raw format ++ iotests.main(supported_fmts=['raw'], ++ supported_protocols=['file']) +diff --git a/tests/qemu-iotests/tests/block-status-cache.out b/tests/qemu-iotests/tests/block-status-cache.out +new file mode 100644 +index 0000000000..ae1213e6f8 +--- /dev/null ++++ b/tests/qemu-iotests/tests/block-status-cache.out +@@ -0,0 +1,5 @@ ++. ++---------------------------------------------------------------------- ++Ran 1 tests ++ ++OK +-- +2.27.0 + diff --git a/SOURCES/kvm-iotests-stream-error-on-reset-New-test.patch b/SOURCES/kvm-iotests-stream-error-on-reset-New-test.patch new file mode 100644 index 0000000..cf69e38 --- /dev/null +++ b/SOURCES/kvm-iotests-stream-error-on-reset-New-test.patch @@ -0,0 +1,196 @@ +From 300f912d4a5afe4ecca9c68a71429fbc9966ec34 Mon Sep 17 00:00:00 2001 +From: Hanna Reitz +Date: Tue, 11 Jan 2022 15:36:13 +0000 +Subject: [PATCH 11/12] iotests/stream-error-on-reset: New test + +RH-Author: Hanna Reitz +RH-MergeRequest: 71: block-backend: prevent dangling BDS pointers across aio_poll() +RH-Commit: [2/2] 3167f31b91eb433f338564201f4ef336e39f7f7d (hreitz/qemu-kvm-c-9-s) +RH-Bugzilla: 2040123 +RH-Acked-by: Kevin Wolf +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Emanuele Giuseppe Esposito + +Test the following scenario: +- Simple stream block in two-layer backing chain (base and top) +- The job is drained via blk_drain(), then an error occurs while the job + settles the ongoing request +- And so the job completes while in blk_drain() + +This was reported as a segfault, but is fixed by "block-backend: prevent +dangling BDS pointers across aio_poll()". + +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2036178 +Signed-off-by: Hanna Reitz +Signed-off-by: Stefan Hajnoczi +Message-Id: <20220111153613.25453-3-stefanha@redhat.com> +Signed-off-by: Kevin Wolf +(cherry picked from commit 2ca1d5d6b91f8a52a5c651f660b2f58c94bf97ba) +Signed-off-by: Hanna Reitz +--- + .../qemu-iotests/tests/stream-error-on-reset | 140 ++++++++++++++++++ + .../tests/stream-error-on-reset.out | 5 + + 2 files changed, 145 insertions(+) + create mode 100755 tests/qemu-iotests/tests/stream-error-on-reset + create mode 100644 tests/qemu-iotests/tests/stream-error-on-reset.out + +diff --git a/tests/qemu-iotests/tests/stream-error-on-reset b/tests/qemu-iotests/tests/stream-error-on-reset +new file mode 100755 +index 0000000000..7eaedb24d7 +--- /dev/null ++++ b/tests/qemu-iotests/tests/stream-error-on-reset +@@ -0,0 +1,140 @@ ++#!/usr/bin/env python3 ++# group: rw quick ++# ++# Test what happens when a stream job completes in a blk_drain(). ++# ++# Copyright (C) 2022 Red Hat, Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++ ++import os ++import iotests ++from iotests import imgfmt, qemu_img_create, qemu_io_silent, QMPTestCase ++ ++ ++image_size = 1 * 1024 * 1024 ++data_size = 64 * 1024 ++base = os.path.join(iotests.test_dir, 'base.img') ++top = os.path.join(iotests.test_dir, 'top.img') ++ ++ ++# We want to test completing a stream job in a blk_drain(). ++# ++# The blk_drain() we are going to use is a virtio-scsi device resetting, ++# which we can trigger by resetting the system. ++# ++# In order to have the block job complete on drain, we (1) throttle its ++# base image so we can start the drain after it has begun, but before it ++# completes, and (2) make it encounter an I/O error on the ensuing write. ++# (If it completes regularly, the completion happens after the drain for ++# some reason.) ++ ++class TestStreamErrorOnReset(QMPTestCase): ++ def setUp(self) -> None: ++ """ ++ Create two images: ++ - base image {base} with {data_size} bytes allocated ++ - top image {top} without any data allocated ++ ++ And the following VM configuration: ++ - base image throttled to {data_size} ++ - top image with a blkdebug configuration so the first write access ++ to it will result in an error ++ - top image is attached to a virtio-scsi device ++ """ ++ assert qemu_img_create('-f', imgfmt, base, str(image_size)) == 0 ++ assert qemu_io_silent('-c', f'write 0 {data_size}', base) == 0 ++ assert qemu_img_create('-f', imgfmt, top, str(image_size)) == 0 ++ ++ self.vm = iotests.VM() ++ self.vm.add_args('-accel', 'tcg') # Make throttling work properly ++ self.vm.add_object(self.vm.qmp_to_opts({ ++ 'qom-type': 'throttle-group', ++ 'id': 'thrgr', ++ 'x-bps-total': str(data_size) ++ })) ++ self.vm.add_blockdev(self.vm.qmp_to_opts({ ++ 'driver': imgfmt, ++ 'node-name': 'base', ++ 'file': { ++ 'driver': 'throttle', ++ 'throttle-group': 'thrgr', ++ 'file': { ++ 'driver': 'file', ++ 'filename': base ++ } ++ } ++ })) ++ self.vm.add_blockdev(self.vm.qmp_to_opts({ ++ 'driver': imgfmt, ++ 'node-name': 'top', ++ 'file': { ++ 'driver': 'blkdebug', ++ 'node-name': 'top-blkdebug', ++ 'inject-error': [{ ++ 'event': 'pwritev', ++ 'immediately': 'true', ++ 'once': 'true' ++ }], ++ 'image': { ++ 'driver': 'file', ++ 'filename': top ++ } ++ }, ++ 'backing': 'base' ++ })) ++ self.vm.add_device(self.vm.qmp_to_opts({ ++ 'driver': 'virtio-scsi', ++ 'id': 'vscsi' ++ })) ++ self.vm.add_device(self.vm.qmp_to_opts({ ++ 'driver': 'scsi-hd', ++ 'bus': 'vscsi.0', ++ 'drive': 'top' ++ })) ++ self.vm.launch() ++ ++ def tearDown(self) -> None: ++ self.vm.shutdown() ++ os.remove(top) ++ os.remove(base) ++ ++ def test_stream_error_on_reset(self) -> None: ++ # Launch a stream job, which will take at least a second to ++ # complete, because the base image is throttled (so we can ++ # get in between it having started and it having completed) ++ res = self.vm.qmp('block-stream', job_id='stream', device='top') ++ self.assert_qmp(res, 'return', {}) ++ ++ while True: ++ ev = self.vm.event_wait('JOB_STATUS_CHANGE') ++ if ev['data']['status'] == 'running': ++ # Once the stream job is running, reset the system, which ++ # forces the virtio-scsi device to be reset, thus draining ++ # the stream job, and making it complete. Completing ++ # inside of that drain should not result in a segfault. ++ res = self.vm.qmp('system_reset') ++ self.assert_qmp(res, 'return', {}) ++ elif ev['data']['status'] == 'null': ++ # The test is done once the job is gone ++ break ++ ++ ++if __name__ == '__main__': ++ # Passes with any format with backing file support, but qed and ++ # qcow1 do not seem to exercise the used-to-be problematic code ++ # path, so there is no point in having them in this list ++ iotests.main(supported_fmts=['qcow2', 'vmdk'], ++ supported_protocols=['file']) +diff --git a/tests/qemu-iotests/tests/stream-error-on-reset.out b/tests/qemu-iotests/tests/stream-error-on-reset.out +new file mode 100644 +index 0000000000..ae1213e6f8 +--- /dev/null ++++ b/tests/qemu-iotests/tests/stream-error-on-reset.out +@@ -0,0 +1,5 @@ ++. ++---------------------------------------------------------------------- ++Ran 1 tests ++ ++OK +-- +2.27.0 + diff --git a/SOURCES/kvm-iotests.py-Add-QemuStorageDaemon-class.patch b/SOURCES/kvm-iotests.py-Add-QemuStorageDaemon-class.patch new file mode 100644 index 0000000..b215d23 --- /dev/null +++ b/SOURCES/kvm-iotests.py-Add-QemuStorageDaemon-class.patch @@ -0,0 +1,92 @@ +From c21502a220d107261c9a8627158f357489d86543 Mon Sep 17 00:00:00 2001 +From: Hanna Reitz +Date: Fri, 4 Feb 2022 12:10:09 +0100 +Subject: [PATCH 5/8] iotests.py: Add QemuStorageDaemon class + +RH-Author: Hanna Reitz +RH-MergeRequest: 74: block/nbd: Handle AioContext changes +RH-Commit: [3/6] 5da1cda4d025c1bd7029ed8071b4ccf25459a878 (hreitz/qemu-kvm-c-9-s) +RH-Bugzilla: 2033626 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi + +This is a rather simple class that allows creating a QSD instance +running in the background and stopping it when no longer needed. + +The __del__ handler is a safety net for when something goes so wrong in +a test that e.g. the tearDown() method is not called (e.g. setUp() +launches the QSD, but then launching a VM fails). We do not want the +QSD to continue running after the test has failed, so __del__() will +take care to kill it. + +Reviewed-by: Vladimir Sementsov-Ogievskiy +Signed-off-by: Hanna Reitz +Signed-off-by: Vladimir Sementsov-Ogievskiy +(cherry picked from commit 091dc7b2b5553a529bff9a7bf9ad3bc85bc5bdcd) +Signed-off-by: Hanna Reitz +--- + tests/qemu-iotests/iotests.py | 40 +++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py +index 83bfedb902..a51b5ce8cd 100644 +--- a/tests/qemu-iotests/iotests.py ++++ b/tests/qemu-iotests/iotests.py +@@ -72,6 +72,8 @@ + qemu_prog = os.environ.get('QEMU_PROG', 'qemu') + qemu_opts = os.environ.get('QEMU_OPTIONS', '').strip().split(' ') + ++qsd_prog = os.environ.get('QSD_PROG', 'qemu-storage-daemon') ++ + gdb_qemu_env = os.environ.get('GDB_OPTIONS') + qemu_gdb = [] + if gdb_qemu_env: +@@ -312,6 +314,44 @@ def cmd(self, cmd): + return self._read_output() + + ++class QemuStorageDaemon: ++ def __init__(self, *args: str, instance_id: str = 'a'): ++ assert '--pidfile' not in args ++ self.pidfile = os.path.join(test_dir, f'qsd-{instance_id}-pid') ++ all_args = [qsd_prog] + list(args) + ['--pidfile', self.pidfile] ++ ++ # Cannot use with here, we want the subprocess to stay around ++ # pylint: disable=consider-using-with ++ self._p = subprocess.Popen(all_args) ++ while not os.path.exists(self.pidfile): ++ if self._p.poll() is not None: ++ cmd = ' '.join(all_args) ++ raise RuntimeError( ++ 'qemu-storage-daemon terminated with exit code ' + ++ f'{self._p.returncode}: {cmd}') ++ ++ time.sleep(0.01) ++ ++ with open(self.pidfile, encoding='utf-8') as f: ++ self._pid = int(f.read().strip()) ++ ++ assert self._pid == self._p.pid ++ ++ def stop(self, kill_signal=15): ++ self._p.send_signal(kill_signal) ++ self._p.wait() ++ self._p = None ++ ++ try: ++ os.remove(self.pidfile) ++ except OSError: ++ pass ++ ++ def __del__(self): ++ if self._p is not None: ++ self.stop(kill_signal=9) ++ ++ + def qemu_nbd(*args): + '''Run qemu-nbd in daemon mode and return the parent's exit code''' + return subprocess.call(qemu_nbd_args + ['--fork'] + list(args)) +-- +2.27.0 + diff --git a/SOURCES/kvm-numa-Enable-numa-for-SGX-EPC-sections.patch b/SOURCES/kvm-numa-Enable-numa-for-SGX-EPC-sections.patch new file mode 100644 index 0000000..e26bfcf --- /dev/null +++ b/SOURCES/kvm-numa-Enable-numa-for-SGX-EPC-sections.patch @@ -0,0 +1,287 @@ +From 6274a2a09a8931188889467b104bf2e2fc39cb54 Mon Sep 17 00:00:00 2001 +From: Yang Zhong +Date: Mon, 1 Nov 2021 12:20:05 -0400 +Subject: [PATCH 01/12] numa: Enable numa for SGX EPC sections + +RH-Author: Paul Lai +RH-MergeRequest: 65: Enable SGX and add SGX Numa support +RH-Commit: [1/5] ff69d138c3f5903096388ec7ccf8dc5e6c6c6ffb +RH-Bugzilla: 2033708 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Bandan Das +RH-Acked-by: Cornelia Huck + +The basic SGX did not enable numa for SGX EPC sections, which +result in all EPC sections located in numa node 0. This patch +enable SGX numa function in the guest and the EPC section can +work with RAM as one numa node. + +The Guest kernel related log: +[ 0.009981] ACPI: SRAT: Node 0 PXM 0 [mem 0x180000000-0x183ffffff] +[ 0.009982] ACPI: SRAT: Node 1 PXM 1 [mem 0x184000000-0x185bfffff] +The SRAT table can normally show SGX EPC sections menory info in different +numa nodes. + +The SGX EPC numa related command: + ...... + -m 4G,maxmem=20G \ + -smp sockets=2,cores=2 \ + -cpu host,+sgx-provisionkey \ + -object memory-backend-ram,size=2G,host-nodes=0,policy=bind,id=node0 \ + -object memory-backend-epc,id=mem0,size=64M,prealloc=on,host-nodes=0,policy=bind \ + -numa node,nodeid=0,cpus=0-1,memdev=node0 \ + -object memory-backend-ram,size=2G,host-nodes=1,policy=bind,id=node1 \ + -object memory-backend-epc,id=mem1,size=28M,prealloc=on,host-nodes=1,policy=bind \ + -numa node,nodeid=1,cpus=2-3,memdev=node1 \ + -M sgx-epc.0.memdev=mem0,sgx-epc.0.node=0,sgx-epc.1.memdev=mem1,sgx-epc.1.node=1 \ + ...... + +Signed-off-by: Yang Zhong +Message-Id: <20211101162009.62161-2-yang.zhong@intel.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 1105812382e1126d86dddc16b3700f8c79dc93d1) +Signed-off-by: Paul Lai +--- + hw/core/numa.c | 5 ++--- + hw/i386/acpi-build.c | 2 ++ + hw/i386/sgx-epc.c | 3 +++ + hw/i386/sgx-stub.c | 4 ++++ + hw/i386/sgx.c | 44 +++++++++++++++++++++++++++++++++++++++ + include/hw/i386/sgx-epc.h | 3 +++ + monitor/hmp-cmds.c | 1 + + qapi/machine.json | 10 ++++++++- + qemu-options.hx | 4 ++-- + 9 files changed, 70 insertions(+), 6 deletions(-) + +diff --git a/hw/core/numa.c b/hw/core/numa.c +index e6050b2273..1aa05dcf42 100644 +--- a/hw/core/numa.c ++++ b/hw/core/numa.c +@@ -784,9 +784,8 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[]) + break; + case MEMORY_DEVICE_INFO_KIND_SGX_EPC: + se = value->u.sgx_epc.data; +- /* TODO: once we support numa, assign to right node */ +- node_mem[0].node_mem += se->size; +- node_mem[0].node_plugged_mem += se->size; ++ node_mem[se->node].node_mem += se->size; ++ node_mem[se->node].node_plugged_mem = 0; + break; + default: + g_assert_not_reached(); +diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c +index a99c6e4fe3..8383b83ee3 100644 +--- a/hw/i386/acpi-build.c ++++ b/hw/i386/acpi-build.c +@@ -2068,6 +2068,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) + nvdimm_build_srat(table_data); + } + ++ sgx_epc_build_srat(table_data); ++ + /* + * TODO: this part is not in ACPI spec and current linux kernel boots fine + * without these entries. But I recall there were issues the last time I +diff --git a/hw/i386/sgx-epc.c b/hw/i386/sgx-epc.c +index e508827e78..96b2940d75 100644 +--- a/hw/i386/sgx-epc.c ++++ b/hw/i386/sgx-epc.c +@@ -21,6 +21,7 @@ + + static Property sgx_epc_properties[] = { + DEFINE_PROP_UINT64(SGX_EPC_ADDR_PROP, SGXEPCDevice, addr, 0), ++ DEFINE_PROP_UINT32(SGX_EPC_NUMA_NODE_PROP, SGXEPCDevice, node, 0), + DEFINE_PROP_LINK(SGX_EPC_MEMDEV_PROP, SGXEPCDevice, hostmem, + TYPE_MEMORY_BACKEND_EPC, HostMemoryBackendEpc *), + DEFINE_PROP_END_OF_LIST(), +@@ -139,6 +140,8 @@ static void sgx_epc_md_fill_device_info(const MemoryDeviceState *md, + se->memaddr = epc->addr; + se->size = object_property_get_uint(OBJECT(epc), SGX_EPC_SIZE_PROP, + NULL); ++ se->node = object_property_get_uint(OBJECT(epc), SGX_EPC_NUMA_NODE_PROP, ++ NULL); + se->memdev = object_get_canonical_path(OBJECT(epc->hostmem)); + + info->u.sgx_epc.data = se; +diff --git a/hw/i386/sgx-stub.c b/hw/i386/sgx-stub.c +index c9b379e665..26833eb233 100644 +--- a/hw/i386/sgx-stub.c ++++ b/hw/i386/sgx-stub.c +@@ -6,6 +6,10 @@ + #include "qapi/error.h" + #include "qapi/qapi-commands-misc-target.h" + ++void sgx_epc_build_srat(GArray *table_data) ++{ ++} ++ + SGXInfo *qmp_query_sgx(Error **errp) + { + error_setg(errp, "SGX support is not compiled in"); +diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c +index 8fef3dd8fa..d04299904a 100644 +--- a/hw/i386/sgx.c ++++ b/hw/i386/sgx.c +@@ -23,6 +23,7 @@ + #include "sysemu/hw_accel.h" + #include "sysemu/reset.h" + #include ++#include "hw/acpi/aml-build.h" + + #define SGX_MAX_EPC_SECTIONS 8 + #define SGX_CPUID_EPC_INVALID 0x0 +@@ -36,6 +37,46 @@ + + #define RETRY_NUM 2 + ++static int sgx_epc_device_list(Object *obj, void *opaque) ++{ ++ GSList **list = opaque; ++ ++ if (object_dynamic_cast(obj, TYPE_SGX_EPC)) { ++ *list = g_slist_append(*list, DEVICE(obj)); ++ } ++ ++ object_child_foreach(obj, sgx_epc_device_list, opaque); ++ return 0; ++} ++ ++static GSList *sgx_epc_get_device_list(void) ++{ ++ GSList *list = NULL; ++ ++ object_child_foreach(qdev_get_machine(), sgx_epc_device_list, &list); ++ return list; ++} ++ ++void sgx_epc_build_srat(GArray *table_data) ++{ ++ GSList *device_list = sgx_epc_get_device_list(); ++ ++ for (; device_list; device_list = device_list->next) { ++ DeviceState *dev = device_list->data; ++ Object *obj = OBJECT(dev); ++ uint64_t addr, size; ++ int node; ++ ++ node = object_property_get_uint(obj, SGX_EPC_NUMA_NODE_PROP, ++ &error_abort); ++ addr = object_property_get_uint(obj, SGX_EPC_ADDR_PROP, &error_abort); ++ size = object_property_get_uint(obj, SGX_EPC_SIZE_PROP, &error_abort); ++ ++ build_srat_memory(table_data, addr, size, node, MEM_AFFINITY_ENABLED); ++ } ++ g_slist_free(device_list); ++} ++ + static uint64_t sgx_calc_section_metric(uint64_t low, uint64_t high) + { + return (low & MAKE_64BIT_MASK(12, 20)) + +@@ -226,6 +267,9 @@ void pc_machine_init_sgx_epc(PCMachineState *pcms) + /* set the memdev link with memory backend */ + object_property_parse(obj, SGX_EPC_MEMDEV_PROP, list->value->memdev, + &error_fatal); ++ /* set the numa node property for sgx epc object */ ++ object_property_set_uint(obj, SGX_EPC_NUMA_NODE_PROP, list->value->node, ++ &error_fatal); + object_property_set_bool(obj, "realized", true, &error_fatal); + object_unref(obj); + } +diff --git a/include/hw/i386/sgx-epc.h b/include/hw/i386/sgx-epc.h +index a6a65be854..581fac389a 100644 +--- a/include/hw/i386/sgx-epc.h ++++ b/include/hw/i386/sgx-epc.h +@@ -25,6 +25,7 @@ + #define SGX_EPC_ADDR_PROP "addr" + #define SGX_EPC_SIZE_PROP "size" + #define SGX_EPC_MEMDEV_PROP "memdev" ++#define SGX_EPC_NUMA_NODE_PROP "node" + + /** + * SGXEPCDevice: +@@ -38,6 +39,7 @@ typedef struct SGXEPCDevice { + + /* public */ + uint64_t addr; ++ uint32_t node; + HostMemoryBackendEpc *hostmem; + } SGXEPCDevice; + +@@ -56,6 +58,7 @@ typedef struct SGXEPCState { + } SGXEPCState; + + bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size); ++void sgx_epc_build_srat(GArray *table_data); + + static inline uint64_t sgx_epc_above_4g_end(SGXEPCState *sgx_epc) + { +diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c +index 9c91bf93e9..2669156b28 100644 +--- a/monitor/hmp-cmds.c ++++ b/monitor/hmp-cmds.c +@@ -1810,6 +1810,7 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) + se->id ? se->id : ""); + monitor_printf(mon, " memaddr: 0x%" PRIx64 "\n", se->memaddr); + monitor_printf(mon, " size: %" PRIu64 "\n", se->size); ++ monitor_printf(mon, " node: %" PRId64 "\n", se->node); + monitor_printf(mon, " memdev: %s\n", se->memdev); + break; + default: +diff --git a/qapi/machine.json b/qapi/machine.json +index 067e3f5378..16e771affc 100644 +--- a/qapi/machine.json ++++ b/qapi/machine.json +@@ -1207,12 +1207,15 @@ + # + # @memdev: memory backend linked with device + # ++# @node: the numa node ++# + # Since: 6.2 + ## + { 'struct': 'SgxEPCDeviceInfo', + 'data': { '*id': 'str', + 'memaddr': 'size', + 'size': 'size', ++ 'node': 'int', + 'memdev': 'str' + } + } +@@ -1285,10 +1288,15 @@ + # + # @memdev: memory backend linked with device + # ++# @node: the numa node ++# + # Since: 6.2 + ## + { 'struct': 'SgxEPC', +- 'data': { 'memdev': 'str' } } ++ 'data': { 'memdev': 'str', ++ 'node': 'int' ++ } ++} + + ## + # @SgxEPCProperties: +diff --git a/qemu-options.hx b/qemu-options.hx +index 94c4a8dbaf..4b7798088b 100644 +--- a/qemu-options.hx ++++ b/qemu-options.hx +@@ -127,11 +127,11 @@ SRST + ERST + + DEF("M", HAS_ARG, QEMU_OPTION_M, +- " sgx-epc.0.memdev=memid\n", ++ " sgx-epc.0.memdev=memid,sgx-epc.0.node=numaid\n", + QEMU_ARCH_ALL) + + SRST +-``sgx-epc.0.memdev=@var{memid}`` ++``sgx-epc.0.memdev=@var{memid},sgx-epc.0.node=@var{numaid}`` + Define an SGX EPC section. + ERST + +-- +2.27.0 + diff --git a/SOURCES/kvm-numa-Support-SGX-numa-in-the-monitor-and-Libvirt-int.patch b/SOURCES/kvm-numa-Support-SGX-numa-in-the-monitor-and-Libvirt-int.patch new file mode 100644 index 0000000..de4c4b1 --- /dev/null +++ b/SOURCES/kvm-numa-Support-SGX-numa-in-the-monitor-and-Libvirt-int.patch @@ -0,0 +1,210 @@ +From 0f75501ba348dc9fb3ce0198ceafc8093149457d Mon Sep 17 00:00:00 2001 +From: Yang Zhong +Date: Mon, 1 Nov 2021 12:20:07 -0400 +Subject: [PATCH 02/12] numa: Support SGX numa in the monitor and Libvirt + interfaces + +RH-Author: Paul Lai +RH-MergeRequest: 65: Enable SGX and add SGX Numa support +RH-Commit: [2/5] 8c19cfb1a139fd4dbac771e695a133f16a68437f +RH-Bugzilla: 2033708 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Bandan Das +RH-Acked-by: Cornelia Huck + +Add the SGXEPCSection list into SGXInfo to show the multiple +SGX EPC sections detailed info, not the total size like before. +This patch can enable numa support for 'info sgx' command and +QMP interfaces. The new interfaces show each EPC section info +in one numa node. Libvirt can use QMP interface to get the +detailed host SGX EPC capabilities to decide how to allocate +host EPC sections to guest. + +(qemu) info sgx + SGX support: enabled + SGX1 support: enabled + SGX2 support: enabled + FLC support: enabled + NUMA node #0: size=67108864 + NUMA node #1: size=29360128 + +The QMP interface show: +(QEMU) query-sgx +{"return": {"sgx": true, "sgx2": true, "sgx1": true, "sections": \ +[{"node": 0, "size": 67108864}, {"node": 1, "size": 29360128}], "flc": true}} + +(QEMU) query-sgx-capabilities +{"return": {"sgx": true, "sgx2": true, "sgx1": true, "sections": \ +[{"node": 0, "size": 17070817280}, {"node": 1, "size": 17079205888}], "flc": true}} + +Signed-off-by: Yang Zhong +Message-Id: <20211101162009.62161-4-yang.zhong@intel.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit 4755927ae12547c2e7cb22c5fa1b39038c6c11b1) +Signed-off-by: Paul Lai +--- + hw/i386/sgx.c | 51 +++++++++++++++++++++++++++++++++++-------- + qapi/misc-target.json | 19 ++++++++++++++-- + 2 files changed, 59 insertions(+), 11 deletions(-) + +diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c +index d04299904a..5de5dd0893 100644 +--- a/hw/i386/sgx.c ++++ b/hw/i386/sgx.c +@@ -83,11 +83,13 @@ static uint64_t sgx_calc_section_metric(uint64_t low, uint64_t high) + ((high & MAKE_64BIT_MASK(0, 20)) << 32); + } + +-static uint64_t sgx_calc_host_epc_section_size(void) ++static SGXEPCSectionList *sgx_calc_host_epc_sections(void) + { ++ SGXEPCSectionList *head = NULL, **tail = &head; ++ SGXEPCSection *section; + uint32_t i, type; + uint32_t eax, ebx, ecx, edx; +- uint64_t size = 0; ++ uint32_t j = 0; + + for (i = 0; i < SGX_MAX_EPC_SECTIONS; i++) { + host_cpuid(0x12, i + 2, &eax, &ebx, &ecx, &edx); +@@ -101,10 +103,13 @@ static uint64_t sgx_calc_host_epc_section_size(void) + break; + } + +- size += sgx_calc_section_metric(ecx, edx); ++ section = g_new0(SGXEPCSection, 1); ++ section->node = j++; ++ section->size = sgx_calc_section_metric(ecx, edx); ++ QAPI_LIST_APPEND(tail, section); + } + +- return size; ++ return head; + } + + static void sgx_epc_reset(void *opaque) +@@ -168,13 +173,35 @@ SGXInfo *qmp_query_sgx_capabilities(Error **errp) + info->sgx1 = eax & (1U << 0) ? true : false; + info->sgx2 = eax & (1U << 1) ? true : false; + +- info->section_size = sgx_calc_host_epc_section_size(); ++ info->sections = sgx_calc_host_epc_sections(); + + close(fd); + + return info; + } + ++static SGXEPCSectionList *sgx_get_epc_sections_list(void) ++{ ++ GSList *device_list = sgx_epc_get_device_list(); ++ SGXEPCSectionList *head = NULL, **tail = &head; ++ SGXEPCSection *section; ++ ++ for (; device_list; device_list = device_list->next) { ++ DeviceState *dev = device_list->data; ++ Object *obj = OBJECT(dev); ++ ++ section = g_new0(SGXEPCSection, 1); ++ section->node = object_property_get_uint(obj, SGX_EPC_NUMA_NODE_PROP, ++ &error_abort); ++ section->size = object_property_get_uint(obj, SGX_EPC_SIZE_PROP, ++ &error_abort); ++ QAPI_LIST_APPEND(tail, section); ++ } ++ g_slist_free(device_list); ++ ++ return head; ++} ++ + SGXInfo *qmp_query_sgx(Error **errp) + { + SGXInfo *info = NULL; +@@ -193,14 +220,13 @@ SGXInfo *qmp_query_sgx(Error **errp) + return NULL; + } + +- SGXEPCState *sgx_epc = &pcms->sgx_epc; + info = g_new0(SGXInfo, 1); + + info->sgx = true; + info->sgx1 = true; + info->sgx2 = true; + info->flc = true; +- info->section_size = sgx_epc->size; ++ info->sections = sgx_get_epc_sections_list(); + + return info; + } +@@ -208,6 +234,7 @@ SGXInfo *qmp_query_sgx(Error **errp) + void hmp_info_sgx(Monitor *mon, const QDict *qdict) + { + Error *err = NULL; ++ SGXEPCSectionList *section_list, *section; + g_autoptr(SGXInfo) info = qmp_query_sgx(&err); + + if (err) { +@@ -222,8 +249,14 @@ void hmp_info_sgx(Monitor *mon, const QDict *qdict) + info->sgx2 ? "enabled" : "disabled"); + monitor_printf(mon, "FLC support: %s\n", + info->flc ? "enabled" : "disabled"); +- monitor_printf(mon, "size: %" PRIu64 "\n", +- info->section_size); ++ ++ section_list = info->sections; ++ for (section = section_list; section; section = section->next) { ++ monitor_printf(mon, "NUMA node #%" PRId64 ": ", ++ section->value->node); ++ monitor_printf(mon, "size=%" PRIu64 "\n", ++ section->value->size); ++ } + } + + bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size) +diff --git a/qapi/misc-target.json b/qapi/misc-target.json +index 5aa2b95b7d..1022aa0184 100644 +--- a/qapi/misc-target.json ++++ b/qapi/misc-target.json +@@ -337,6 +337,21 @@ + 'if': 'TARGET_ARM' } + + ++## ++# @SGXEPCSection: ++# ++# Information about intel SGX EPC section info ++# ++# @node: the numa node ++# ++# @size: the size of epc section ++# ++# Since: 6.2 ++## ++{ 'struct': 'SGXEPCSection', ++ 'data': { 'node': 'int', ++ 'size': 'uint64'}} ++ + ## + # @SGXInfo: + # +@@ -350,7 +365,7 @@ + # + # @flc: true if FLC is supported + # +-# @section-size: The EPC section size for guest ++# @sections: The EPC sections info for guest + # + # Since: 6.2 + ## +@@ -359,7 +374,7 @@ + 'sgx1': 'bool', + 'sgx2': 'bool', + 'flc': 'bool', +- 'section-size': 'uint64'}, ++ 'sections': ['SGXEPCSection']}, + 'if': 'TARGET_I386' } + + ## +-- +2.27.0 + diff --git a/SOURCES/kvm-qapi-Cleanup-SGX-related-comments-and-restore-sectio.patch b/SOURCES/kvm-qapi-Cleanup-SGX-related-comments-and-restore-sectio.patch new file mode 100644 index 0000000..9e58f6c --- /dev/null +++ b/SOURCES/kvm-qapi-Cleanup-SGX-related-comments-and-restore-sectio.patch @@ -0,0 +1,213 @@ +From a6a327ae392c02b8e8c75b5d702d929ff8fe408d Mon Sep 17 00:00:00 2001 +From: Yang Zhong +Date: Thu, 20 Jan 2022 17:31:04 -0500 +Subject: [PATCH 05/12] qapi: Cleanup SGX related comments and restore + @section-size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Paul Lai +RH-MergeRequest: 65: Enable SGX and add SGX Numa support +RH-Commit: [5/5] 0d3b9f37cd3cce202050ba3bd51eef4410ef3d38 +RH-Bugzilla: 2033708 +RH-Acked-by: Paolo Bonzini +RH-Acked-by: Bandan Das +RH-Acked-by: Cornelia Huck + +The SGX NUMA patches were merged into Qemu 7.0 release, we need +clarify detailed version history information and also change +some related comments, which make SGX related comments clearer. + +The QMP command schema promises backwards compatibility as standard. +We temporarily restore "@section-size", which can avoid incompatible +API breakage. The "@section-size" will be deprecated in 7.2 version. + +Suggested-by: Daniel P. Berrangé +Signed-off-by: Yang Zhong +Reviewed-by: Daniel P. Berrangé +Reviewed-by: Philippe Mathieu-Daudé +Message-Id: <20220120223104.437161-1-yang.zhong@intel.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Paul Lai +--- + docs/about/deprecated.rst | 13 +++++++++++++ + hw/i386/sgx.c | 11 +++++++++-- + qapi/machine.json | 4 ++-- + qapi/misc-target.json | 22 +++++++++++++++++----- + 4 files changed, 41 insertions(+), 9 deletions(-) + +diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst +index ff7488cb63..33925edf45 100644 +--- a/docs/about/deprecated.rst ++++ b/docs/about/deprecated.rst +@@ -270,6 +270,19 @@ accepted incorrect commands will return an error. Users should make sure that + all arguments passed to ``device_add`` are consistent with the documented + property types. + ++``query-sgx`` return value member ``section-size`` (since 7.0) ++'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ++ ++Member ``section-size`` in return value elements with meta-type ``uint64`` is ++deprecated. Use ``sections`` instead. ++ ++ ++``query-sgx-capabilities`` return value member ``section-size`` (since 7.0) ++''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ++ ++Member ``section-size`` in return value elements with meta-type ``uint64`` is ++deprecated. Use ``sections`` instead. ++ + System accelerators + ------------------- + +diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c +index 5de5dd0893..a2b318dd93 100644 +--- a/hw/i386/sgx.c ++++ b/hw/i386/sgx.c +@@ -83,7 +83,7 @@ static uint64_t sgx_calc_section_metric(uint64_t low, uint64_t high) + ((high & MAKE_64BIT_MASK(0, 20)) << 32); + } + +-static SGXEPCSectionList *sgx_calc_host_epc_sections(void) ++static SGXEPCSectionList *sgx_calc_host_epc_sections(uint64_t *size) + { + SGXEPCSectionList *head = NULL, **tail = &head; + SGXEPCSection *section; +@@ -106,6 +106,7 @@ static SGXEPCSectionList *sgx_calc_host_epc_sections(void) + section = g_new0(SGXEPCSection, 1); + section->node = j++; + section->size = sgx_calc_section_metric(ecx, edx); ++ *size += section->size; + QAPI_LIST_APPEND(tail, section); + } + +@@ -156,6 +157,7 @@ SGXInfo *qmp_query_sgx_capabilities(Error **errp) + { + SGXInfo *info = NULL; + uint32_t eax, ebx, ecx, edx; ++ uint64_t size = 0; + + int fd = qemu_open_old("/dev/sgx_vepc", O_RDWR); + if (fd < 0) { +@@ -173,7 +175,8 @@ SGXInfo *qmp_query_sgx_capabilities(Error **errp) + info->sgx1 = eax & (1U << 0) ? true : false; + info->sgx2 = eax & (1U << 1) ? true : false; + +- info->sections = sgx_calc_host_epc_sections(); ++ info->sections = sgx_calc_host_epc_sections(&size); ++ info->section_size = size; + + close(fd); + +@@ -220,12 +223,14 @@ SGXInfo *qmp_query_sgx(Error **errp) + return NULL; + } + ++ SGXEPCState *sgx_epc = &pcms->sgx_epc; + info = g_new0(SGXInfo, 1); + + info->sgx = true; + info->sgx1 = true; + info->sgx2 = true; + info->flc = true; ++ info->section_size = sgx_epc->size; + info->sections = sgx_get_epc_sections_list(); + + return info; +@@ -249,6 +254,8 @@ void hmp_info_sgx(Monitor *mon, const QDict *qdict) + info->sgx2 ? "enabled" : "disabled"); + monitor_printf(mon, "FLC support: %s\n", + info->flc ? "enabled" : "disabled"); ++ monitor_printf(mon, "size: %" PRIu64 "\n", ++ info->section_size); + + section_list = info->sections; + for (section = section_list; section; section = section->next) { +diff --git a/qapi/machine.json b/qapi/machine.json +index 16e771affc..a9f33d0f27 100644 +--- a/qapi/machine.json ++++ b/qapi/machine.json +@@ -1207,7 +1207,7 @@ + # + # @memdev: memory backend linked with device + # +-# @node: the numa node ++# @node: the numa node (Since: 7.0) + # + # Since: 6.2 + ## +@@ -1288,7 +1288,7 @@ + # + # @memdev: memory backend linked with device + # +-# @node: the numa node ++# @node: the numa node (Since: 7.0) + # + # Since: 6.2 + ## +diff --git a/qapi/misc-target.json b/qapi/misc-target.json +index 1022aa0184..4bc45d2474 100644 +--- a/qapi/misc-target.json ++++ b/qapi/misc-target.json +@@ -344,9 +344,9 @@ + # + # @node: the numa node + # +-# @size: the size of epc section ++# @size: the size of EPC section + # +-# Since: 6.2 ++# Since: 7.0 + ## + { 'struct': 'SGXEPCSection', + 'data': { 'node': 'int', +@@ -365,7 +365,13 @@ + # + # @flc: true if FLC is supported + # +-# @sections: The EPC sections info for guest ++# @section-size: The EPC section size for guest ++# Redundant with @sections. Just for backward compatibility. ++# ++# @sections: The EPC sections info for guest (Since: 7.0) ++# ++# Features: ++# @deprecated: Member @section-size is deprecated. Use @sections instead. + # + # Since: 6.2 + ## +@@ -374,6 +380,8 @@ + 'sgx1': 'bool', + 'sgx2': 'bool', + 'flc': 'bool', ++ 'section-size': { 'type': 'uint64', ++ 'features': [ 'deprecated' ] }, + 'sections': ['SGXEPCSection']}, + 'if': 'TARGET_I386' } + +@@ -390,7 +398,9 @@ + # + # -> { "execute": "query-sgx" } + # <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true, +-# "flc": true, "section-size" : 0 } } ++# "flc": true, "section-size" : 96468992, ++# "sections": [{"node": 0, "size": 67108864}, ++# {"node": 1, "size": 29360128}]} } + # + ## + { 'command': 'query-sgx', 'returns': 'SGXInfo', 'if': 'TARGET_I386' } +@@ -408,7 +418,9 @@ + # + # -> { "execute": "query-sgx-capabilities" } + # <- { "return": { "sgx": true, "sgx1" : true, "sgx2" : true, +-# "flc": true, "section-size" : 0 } } ++# "flc": true, "section-size" : 96468992, ++# "section" : [{"node": 0, "size": 67108864}, ++# {"node": 1, "size": 29360128}]} } + # + ## + { 'command': 'query-sgx-capabilities', 'returns': 'SGXInfo', 'if': 'TARGET_I386' } +-- +2.27.0 + diff --git a/SOURCES/kvm-qemu-img-make-is_allocated_sectors-more-efficient.patch b/SOURCES/kvm-qemu-img-make-is_allocated_sectors-more-efficient.patch new file mode 100644 index 0000000..2d67070 --- /dev/null +++ b/SOURCES/kvm-qemu-img-make-is_allocated_sectors-more-efficient.patch @@ -0,0 +1,108 @@ +From a221f5a8ed02690687e6709c49ae0e1e01c5f466 Mon Sep 17 00:00:00 2001 +From: Vladimir Sementsov-Ogievskiy +Date: Fri, 17 Dec 2021 17:46:54 +0100 +Subject: [PATCH 09/12] qemu-img: make is_allocated_sectors() more efficient + +RH-Author: Kevin Wolf +RH-MergeRequest: 70: qemu-img convert: Fix sparseness of output image +RH-Commit: [2/2] cc05aa4ac506b57ff9b430c007618cdf1485a03f (kmwolf/centos-qemu-kvm) +RH-Bugzilla: 1882917 +RH-Acked-by: Eric Blake +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Hanna Reitz + +Consider the case when the whole buffer is zero and end is unaligned. + +If i <= tail, we return 1 and do one unaligned WRITE, RMW happens. + +If i > tail, we do on aligned WRITE_ZERO (or skip if target is zeroed) +and again one unaligned WRITE, RMW happens. + +Let's do better: don't fragment the whole-zero buffer and report it as +ZERO: in case of zeroed target we just do nothing and avoid RMW. If +target is not zeroes, one unaligned WRITE_ZERO should not be much worse +than one unaligned WRITE. + +Signed-off-by: Vladimir Sementsov-Ogievskiy +Message-Id: <20211217164654.1184218-3-vsementsov@virtuozzo.com> +Tested-by: Peter Lieven +Signed-off-by: Kevin Wolf +(cherry picked from commit 96054c76ff2db74165385a69f234c57a6bbc941e) +Signed-off-by: Kevin Wolf +--- + qemu-img.c | 23 +++++++++++++++++++---- + tests/qemu-iotests/122.out | 8 ++------ + 2 files changed, 21 insertions(+), 10 deletions(-) + +diff --git a/qemu-img.c b/qemu-img.c +index f036a1d428..d7ddfcc528 100644 +--- a/qemu-img.c ++++ b/qemu-img.c +@@ -1171,19 +1171,34 @@ static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum, + } + } + ++ if (i == n) { ++ /* ++ * The whole buf is the same. ++ * No reason to split it into chunks, so return now. ++ */ ++ *pnum = i; ++ return !is_zero; ++ } ++ + tail = (sector_num + i) & (alignment - 1); + if (tail) { + if (is_zero && i <= tail) { +- /* treat unallocated areas which only consist +- * of a small tail as allocated. */ ++ /* ++ * For sure next sector after i is data, and it will rewrite this ++ * tail anyway due to RMW. So, let's just write data now. ++ */ + is_zero = false; + } + if (!is_zero) { +- /* align up end offset of allocated areas. */ ++ /* If possible, align up end offset of allocated areas. */ + i += alignment - tail; + i = MIN(i, n); + } else { +- /* align down end offset of zero areas. */ ++ /* ++ * For sure next sector after i is data, and it will rewrite this ++ * tail anyway due to RMW. Better is avoid RMW and write zeroes up ++ * to aligned bound. ++ */ + i -= tail; + } + } +diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out +index 69b8e8b803..e18766e167 100644 +--- a/tests/qemu-iotests/122.out ++++ b/tests/qemu-iotests/122.out +@@ -201,9 +201,7 @@ convert -S 4k + { "start": 8192, "length": 4096, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}, + { "start": 12288, "length": 4096, "depth": 0, "present": false, "zero": true, "data": false}, + { "start": 16384, "length": 4096, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}, +-{ "start": 20480, "length": 46080, "depth": 0, "present": false, "zero": true, "data": false}, +-{ "start": 66560, "length": 1024, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}, +-{ "start": 67584, "length": 67041280, "depth": 0, "present": false, "zero": true, "data": false}] ++{ "start": 20480, "length": 67088384, "depth": 0, "present": false, "zero": true, "data": false}] + + convert -c -S 4k + [{ "start": 0, "length": 1024, "depth": 0, "present": true, "zero": false, "data": true}, +@@ -215,9 +213,7 @@ convert -c -S 4k + + convert -S 8k + [{ "start": 0, "length": 24576, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}, +-{ "start": 24576, "length": 41984, "depth": 0, "present": false, "zero": true, "data": false}, +-{ "start": 66560, "length": 1024, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}, +-{ "start": 67584, "length": 67041280, "depth": 0, "present": false, "zero": true, "data": false}] ++{ "start": 24576, "length": 67084288, "depth": 0, "present": false, "zero": true, "data": false}] + + convert -c -S 8k + [{ "start": 0, "length": 1024, "depth": 0, "present": true, "zero": false, "data": true}, +-- +2.27.0 + diff --git a/SOURCES/kvm-qemu-storage-daemon-Add-vhost-user-blk-help.patch b/SOURCES/kvm-qemu-storage-daemon-Add-vhost-user-blk-help.patch new file mode 100644 index 0000000..bc36f5c --- /dev/null +++ b/SOURCES/kvm-qemu-storage-daemon-Add-vhost-user-blk-help.patch @@ -0,0 +1,72 @@ +From 0f4592f79f8c24f84db18a8c39c6056b2a0be524 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= +Date: Fri, 7 Jan 2022 11:54:19 +0100 +Subject: [PATCH 1/5] qemu-storage-daemon: Add vhost-user-blk help +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Kevin Wolf +RH-MergeRequest: 63: qemu-storage-daemon: Add vhost-user-blk help +RH-Commit: [1/2] 6b08fec5d6ceea9f8f3810321099310069e08b53 (kmwolf/centos-qemu-kvm) +RH-Bugzilla: 1962088 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Hanna Reitz + +Add missing vhost-user-blk help: + + $ qemu-storage-daemon -h + ... + --export [type=]vhost-user-blk,id=,node-name=, + addr.type=unix,addr.path=[,writable=on|off] + [,logical-block-size=][,num-queues=] + export the specified block node as a + vhosts-user-blk device over UNIX domain socket + --export [type=]vhost-user-blk,id=,node-name=, + fd,addr.str=[,writable=on|off] + [,logical-block-size=][,num-queues=] + export the specified block node as a + vhosts-user-blk device over file descriptor + ... + +Fixes: 90fc91d50b7 ("convert vhost-user-blk server to block export API") +Reported-by: Qing Wang +Reviewed-by: Eric Blake +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: Philippe Mathieu-Daudé +Message-Id: <20220107105420.395011-3-f4bug@amsat.org> +Signed-off-by: Kevin Wolf +(cherry picked from commit c8cbc9524269d9583749aaaea8aa244add7e1900) +Signed-off-by: Kevin Wolf +--- + storage-daemon/qemu-storage-daemon.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c +index 52cf17e8ac..9d76d1114d 100644 +--- a/storage-daemon/qemu-storage-daemon.c ++++ b/storage-daemon/qemu-storage-daemon.c +@@ -104,6 +104,19 @@ static void help(void) + " export the specified block node over FUSE\n" + "\n" + #endif /* CONFIG_FUSE */ ++#ifdef CONFIG_VHOST_USER_BLK_SERVER ++" --export [type=]vhost-user-blk,id=,node-name=,\n" ++" addr.type=unix,addr.path=[,writable=on|off]\n" ++" [,logical-block-size=][,num-queues=]\n" ++" export the specified block node as a\n" ++" vhost-user-blk device over UNIX domain socket\n" ++" --export [type=]vhost-user-blk,id=,node-name=,\n" ++" fd,addr.str=[,writable=on|off]\n" ++" [,logical-block-size=][,num-queues=]\n" ++" export the specified block node as a\n" ++" vhost-user-blk device over file descriptor\n" ++"\n" ++#endif /* CONFIG_VHOST_USER_BLK_SERVER */ + " --monitor [chardev=]name[,mode=control][,pretty[=on|off]]\n" + " configure a QMP monitor\n" + "\n" +-- +2.27.0 + diff --git a/SOURCES/kvm-qemu-storage-daemon-Fix-typo-in-vhost-user-blk-help.patch b/SOURCES/kvm-qemu-storage-daemon-Fix-typo-in-vhost-user-blk-help.patch new file mode 100644 index 0000000..798a27e --- /dev/null +++ b/SOURCES/kvm-qemu-storage-daemon-Fix-typo-in-vhost-user-blk-help.patch @@ -0,0 +1,41 @@ +From 20edf203c8cb314e27409918399aa7cbdc6fdb02 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Tue, 25 Jan 2022 16:15:14 +0100 +Subject: [PATCH 2/5] qemu-storage-daemon: Fix typo in vhost-user-blk help + +RH-Author: Kevin Wolf +RH-MergeRequest: 63: qemu-storage-daemon: Add vhost-user-blk help +RH-Commit: [2/2] b7afb670c398799b6e49b926e296771453a55fba (kmwolf/centos-qemu-kvm) +RH-Bugzilla: 1962088 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Hanna Reitz + +The syntax of the fd passing case misses the "addr.type=" key. Add it. + +Signed-off-by: Kevin Wolf +Message-Id: <20220125151514.49035-1-kwolf@redhat.com> +Reviewed-by: Hanna Reitz +Signed-off-by: Kevin Wolf +(cherry picked from commit e66e665f15736f5ee1fbd8087926cb0f1e52f61a) +Signed-off-by: Kevin Wolf +--- + storage-daemon/qemu-storage-daemon.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/storage-daemon/qemu-storage-daemon.c b/storage-daemon/qemu-storage-daemon.c +index 9d76d1114d..ec9aa79b55 100644 +--- a/storage-daemon/qemu-storage-daemon.c ++++ b/storage-daemon/qemu-storage-daemon.c +@@ -111,7 +111,7 @@ static void help(void) + " export the specified block node as a\n" + " vhost-user-blk device over UNIX domain socket\n" + " --export [type=]vhost-user-blk,id=,node-name=,\n" +-" fd,addr.str=[,writable=on|off]\n" ++" addr.type=fd,addr.str=[,writable=on|off]\n" + " [,logical-block-size=][,num-queues=]\n" + " export the specified block node as a\n" + " vhost-user-blk device over file descriptor\n" +-- +2.27.0 + diff --git a/SOURCES/kvm-rhel-machine-types-x86-set-prefer_sockets.patch b/SOURCES/kvm-rhel-machine-types-x86-set-prefer_sockets.patch new file mode 100644 index 0000000..83c912d --- /dev/null +++ b/SOURCES/kvm-rhel-machine-types-x86-set-prefer_sockets.patch @@ -0,0 +1,52 @@ +From ecadfaec992fda7f485522c9ee6e7c9b05614a22 Mon Sep 17 00:00:00 2001 +From: "Dr. David Alan Gilbert" +Date: Tue, 7 Dec 2021 18:39:47 +0000 +Subject: [PATCH 2/2] rhel machine types/x86: set prefer_sockets + +RH-Author: Dr. David Alan Gilbert +RH-MergeRequest: 59: rhel machine types/x86: set prefer_sockets +RH-Commit: [1/1] 9bcd9e2c95154e39ef30a8a342ad6c713fa4f1fb (dagrh/c-9-s-qemu-kvm) +RH-Bugzilla: 2028623 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: quintela1 +RH-Acked-by: Cornelia Huck + +When I fixed up the machine types for 8.5 I missed the + prefer_sockets = true + +add them in; it looks like Power, ARM already have them, and I see them +in thuth's s390 patch. + +Signed-off-by: Dr. David Alan Gilbert +--- + hw/i386/pc_piix.c | 1 + + hw/i386/pc_q35.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c +index 183b5d5464..fccb7f5fc9 100644 +--- a/hw/i386/pc_piix.c ++++ b/hw/i386/pc_piix.c +@@ -973,6 +973,7 @@ static void pc_machine_rhel7_options(MachineClass *m) + compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len); + m->alias = "pc"; + m->is_default = 1; ++ m->smp_props.prefer_sockets = true; + } + + static void pc_init_rhel760(MachineState *machine) +diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c +index 0e7e885e78..3b748ddd7b 100644 +--- a/hw/i386/pc_q35.c ++++ b/hw/i386/pc_q35.c +@@ -662,6 +662,7 @@ static void pc_q35_machine_rhel850_options(MachineClass *m) + hw_compat_rhel_8_5_len); + compat_props_add(m->compat_props, pc_rhel_8_5_compat, + pc_rhel_8_5_compat_len); ++ m->smp_props.prefer_sockets = true; + } + + DEFINE_PC_MACHINE(q35_rhel850, "pc-q35-rhel8.5.0", pc_q35_init_rhel850, +-- +2.27.0 + diff --git a/SOURCES/kvm-softmmu-fix-device-deletion-events-with-device-JSON-.patch b/SOURCES/kvm-softmmu-fix-device-deletion-events-with-device-JSON-.patch new file mode 100644 index 0000000..4ddfbe9 --- /dev/null +++ b/SOURCES/kvm-softmmu-fix-device-deletion-events-with-device-JSON-.patch @@ -0,0 +1,130 @@ +From 005339f7deaee639c38d30e5bf2235c292ce3937 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Wed, 5 Jan 2022 12:38:47 +0000 +Subject: [PATCH 3/3] softmmu: fix device deletion events with -device JSON + syntax +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Kevin Wolf +RH-MergeRequest: 62: Fix hot unplug of devices created with -device JSON syntax +RH-Commit: [1/1] 980e505ba215b5f9324c107481c5bb257ae03f42 (kmwolf/centos-qemu-kvm) +RH-Bugzilla: 2036669 +RH-Acked-by: Daniel P. Berrangé +RH-Acked-by: Laurent Vivier +RH-Acked-by: Jano Tomko + +The -device JSON syntax impl leaks a reference on the created +DeviceState instance. As a result when you hot-unplug the +device, the device_finalize method won't be called and thus +it will fail to emit the required DEVICE_DELETED event. + +A 'json-cli' feature was previously added against the +'device_add' QMP command QAPI schema to indicated to mgmt +apps that -device supported JSON syntax. Given the hotplug +bug that feature flag is not usable for its purpose, so +we add a new 'json-cli-hotplug' feature to indicate the +-device supports JSON without breaking hotplug. + +Fixes: 5dacda5167560b3af8eadbce5814f60ba44b467e +Resolves: https://gitlab.com/qemu-project/qemu/-/issues/802 +Signed-off-by: Daniel P. Berrangé +Message-Id: <20220105123847.4047954-2-berrange@redhat.com> +Reviewed-by: Laurent Vivier +Tested-by: Ján Tomko +Reviewed-by: Thomas Huth +Signed-off-by: Kevin Wolf +(cherry picked from commit 64b4529a432507ee84a924be69a03432639e87ba) +Signed-off-by: Kevin Wolf +--- + qapi/qdev.json | 5 ++++- + softmmu/vl.c | 4 +++- + tests/qtest/device-plug-test.c | 19 +++++++++++++++++++ + 3 files changed, 26 insertions(+), 2 deletions(-) + +diff --git a/qapi/qdev.json b/qapi/qdev.json +index 69656b14df..26cd10106b 100644 +--- a/qapi/qdev.json ++++ b/qapi/qdev.json +@@ -44,6 +44,9 @@ + # @json-cli: If present, the "-device" command line option supports JSON + # syntax with a structure identical to the arguments of this + # command. ++# @json-cli-hotplug: If present, the "-device" command line option supports JSON ++# syntax without the reference counting leak that broke ++# hot-unplug + # + # Notes: + # +@@ -74,7 +77,7 @@ + { 'command': 'device_add', + 'data': {'driver': 'str', '*bus': 'str', '*id': 'str'}, + 'gen': false, # so we can get the additional arguments +- 'features': ['json-cli'] } ++ 'features': ['json-cli', 'json-cli-hotplug'] } + + ## + # @device_del: +diff --git a/softmmu/vl.c b/softmmu/vl.c +index d46b8fb4ab..b3829e2edd 100644 +--- a/softmmu/vl.c ++++ b/softmmu/vl.c +@@ -2690,6 +2690,7 @@ static void qemu_create_cli_devices(void) + qemu_opts_foreach(qemu_find_opts("device"), + device_init_func, NULL, &error_fatal); + QTAILQ_FOREACH(opt, &device_opts, next) { ++ DeviceState *dev; + loc_push_restore(&opt->loc); + /* + * TODO Eventually we should call qmp_device_add() here to make sure it +@@ -2698,7 +2699,8 @@ static void qemu_create_cli_devices(void) + * from the start, so call qdev_device_add_from_qdict() directly for + * now. + */ +- qdev_device_add_from_qdict(opt->opts, true, &error_fatal); ++ dev = qdev_device_add_from_qdict(opt->opts, true, &error_fatal); ++ object_unref(OBJECT(dev)); + loc_pop(&opt->loc); + } + rom_reset_order_override(); +diff --git a/tests/qtest/device-plug-test.c b/tests/qtest/device-plug-test.c +index 559d47727a..ad79bd4c14 100644 +--- a/tests/qtest/device-plug-test.c ++++ b/tests/qtest/device-plug-test.c +@@ -77,6 +77,23 @@ static void test_pci_unplug_request(void) + qtest_quit(qtest); + } + ++static void test_pci_unplug_json_request(void) ++{ ++ QTestState *qtest = qtest_initf( ++ "-device '{\"driver\": \"virtio-mouse-pci\", \"id\": \"dev0\"}'"); ++ ++ /* ++ * Request device removal. As the guest is not running, the request won't ++ * be processed. However during system reset, the removal will be ++ * handled, removing the device. ++ */ ++ device_del(qtest, "dev0"); ++ system_reset(qtest); ++ wait_device_deleted_event(qtest, "dev0"); ++ ++ qtest_quit(qtest); ++} ++ + static void test_ccw_unplug(void) + { + QTestState *qtest = qtest_initf("-device virtio-balloon-ccw,id=dev0"); +@@ -145,6 +162,8 @@ int main(int argc, char **argv) + */ + qtest_add_func("/device-plug/pci-unplug-request", + test_pci_unplug_request); ++ qtest_add_func("/device-plug/pci-unplug-json-request", ++ test_pci_unplug_json_request); + + if (!strcmp(arch, "s390x")) { + qtest_add_func("/device-plug/ccw-unplug", +-- +2.27.0 + diff --git a/SOURCES/kvm-virtiofsd-Drop-membership-of-all-supplementary-group.patch b/SOURCES/kvm-virtiofsd-Drop-membership-of-all-supplementary-group.patch new file mode 100644 index 0000000..539b8fe --- /dev/null +++ b/SOURCES/kvm-virtiofsd-Drop-membership-of-all-supplementary-group.patch @@ -0,0 +1,110 @@ +From 846192d22a1ddfa87682bb0b67febef5c30c9743 Mon Sep 17 00:00:00 2001 +From: Vivek Goyal +Date: Tue, 25 Jan 2022 13:51:14 -0500 +Subject: [PATCH 3/5] virtiofsd: Drop membership of all supplementary groups + (CVE-2022-0358) + +RH-Author: Dr. David Alan Gilbert +RH-MergeRequest: 66: c9s: virtiofsd security fix - drop secondary groups +RH-Commit: [1/1] cdf3b0405ea3369933e76761890f16b040641036 (redhat/centos-stream/src/qemu-kvm) +RH-Bugzilla: 2046201 +RH-Acked-by: Hanna Reitz +RH-Acked-by: Sergio Lopez +RH-Acked-by: Vivek Goyal + +At the start, drop membership of all supplementary groups. This is +not required. + +If we have membership of "root" supplementary group and when we switch +uid/gid using setresuid/setsgid, we still retain membership of existing +supplemntary groups. And that can allow some operations which are not +normally allowed. + +For example, if root in guest creates a dir as follows. + +$ mkdir -m 03777 test_dir + +This sets SGID on dir as well as allows unprivileged users to write into +this dir. + +And now as unprivileged user open file as follows. + +$ su test +$ fd = open("test_dir/priviledge_id", O_RDWR|O_CREAT|O_EXCL, 02755); + +This will create SGID set executable in test_dir/. + +And that's a problem because now an unpriviliged user can execute it, +get egid=0 and get access to resources owned by "root" group. This is +privilege escalation. + +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2044863 +Fixes: CVE-2022-0358 +Reported-by: JIETAO XIAO +Suggested-by: Miklos Szeredi +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Vivek Goyal +Message-Id: +Signed-off-by: Dr. David Alan Gilbert + dgilbert: Fixed missing {}'s style nit +(cherry picked from commit 449e8171f96a6a944d1f3b7d3627ae059eae21ca) +--- + tools/virtiofsd/passthrough_ll.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c +index 64b5b4fbb1..b3d0674f6d 100644 +--- a/tools/virtiofsd/passthrough_ll.c ++++ b/tools/virtiofsd/passthrough_ll.c +@@ -54,6 +54,7 @@ + #include + #include + #include ++#include + + #include "qemu/cutils.h" + #include "passthrough_helpers.h" +@@ -1161,6 +1162,30 @@ static void lo_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) + #define OURSYS_setresuid SYS_setresuid + #endif + ++static void drop_supplementary_groups(void) ++{ ++ int ret; ++ ++ ret = getgroups(0, NULL); ++ if (ret == -1) { ++ fuse_log(FUSE_LOG_ERR, "getgroups() failed with error=%d:%s\n", ++ errno, strerror(errno)); ++ exit(1); ++ } ++ ++ if (!ret) { ++ return; ++ } ++ ++ /* Drop all supplementary groups. We should not need it */ ++ ret = setgroups(0, NULL); ++ if (ret == -1) { ++ fuse_log(FUSE_LOG_ERR, "setgroups() failed with error=%d:%s\n", ++ errno, strerror(errno)); ++ exit(1); ++ } ++} ++ + /* + * Change to uid/gid of caller so that file is created with + * ownership of caller. +@@ -3926,6 +3951,8 @@ int main(int argc, char *argv[]) + + qemu_init_exec_dir(argv[0]); + ++ drop_supplementary_groups(); ++ + pthread_mutex_init(&lo.mutex, NULL); + lo.inodes = g_hash_table_new(lo_key_hash, lo_key_equal); + lo.root.fd = -1; +-- +2.27.0 + diff --git a/SOURCES/kvm-x86-Add-q35-RHEL-8.6.0-machine-type.patch b/SOURCES/kvm-x86-Add-q35-RHEL-8.6.0-machine-type.patch new file mode 100644 index 0000000..eb3273c --- /dev/null +++ b/SOURCES/kvm-x86-Add-q35-RHEL-8.6.0-machine-type.patch @@ -0,0 +1,65 @@ +From 1b8eeb1323fa21c7b26d0396fae5ae4a8cdb1ace Mon Sep 17 00:00:00 2001 +From: "Dr. David Alan Gilbert" +Date: Tue, 11 Jan 2022 18:29:31 +0000 +Subject: [PATCH 1/3] x86: Add q35 RHEL 8.6.0 machine type + +RH-Author: Dr. David Alan Gilbert +RH-MergeRequest: 61: x86: Add rhel 8.6.0 & 9.0.0 machine types +RH-Commit: [1/2] 189335cf0e4ad117e3e401f23aa07cddbbac50df (dagrh/c-9-s-qemu-kvm) +RH-Bugzilla: 1945666 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Cornelia Huck + +Add the new 8.6.0 machine type; note that while the -AV +notation has gone in the product naming, just keep the smbios +definitions the same for consistency. + +Signed-off-by: Dr. David Alan Gilbert +--- + hw/i386/pc_q35.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c +index 3b748ddd7b..0c25305f15 100644 +--- a/hw/i386/pc_q35.c ++++ b/hw/i386/pc_q35.c +@@ -646,6 +646,24 @@ static void pc_q35_machine_rhel_options(MachineClass *m) + compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len); + } + ++static void pc_q35_init_rhel860(MachineState *machine) ++{ ++ pc_q35_init(machine); ++} ++ ++static void pc_q35_machine_rhel860_options(MachineClass *m) ++{ ++ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); ++ pc_q35_machine_rhel_options(m); ++ m->desc = "RHEL-8.6.0 PC (Q35 + ICH9, 2009)"; ++ pcmc->smbios_stream_product = "RHEL-AV"; ++ pcmc->smbios_stream_version = "8.6.0"; ++} ++ ++DEFINE_PC_MACHINE(q35_rhel860, "pc-q35-rhel8.6.0", pc_q35_init_rhel860, ++ pc_q35_machine_rhel860_options); ++ ++ + static void pc_q35_init_rhel850(MachineState *machine) + { + pc_q35_init(machine); +@@ -654,8 +672,9 @@ static void pc_q35_init_rhel850(MachineState *machine) + static void pc_q35_machine_rhel850_options(MachineClass *m) + { + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); +- pc_q35_machine_rhel_options(m); ++ pc_q35_machine_rhel860_options(m); + m->desc = "RHEL-8.5.0 PC (Q35 + ICH9, 2009)"; ++ m->alias = NULL; + pcmc->smbios_stream_product = "RHEL-AV"; + pcmc->smbios_stream_version = "8.5.0"; + compat_props_add(m->compat_props, hw_compat_rhel_8_5, +-- +2.27.0 + diff --git a/SOURCES/kvm-x86-Add-q35-RHEL-9.0.0-machine-type.patch b/SOURCES/kvm-x86-Add-q35-RHEL-9.0.0-machine-type.patch new file mode 100644 index 0000000..4367495 --- /dev/null +++ b/SOURCES/kvm-x86-Add-q35-RHEL-9.0.0-machine-type.patch @@ -0,0 +1,75 @@ +From 3d5024fb9c904a649d07f0def3a90b3d36611215 Mon Sep 17 00:00:00 2001 +From: "Dr. David Alan Gilbert" +Date: Wed, 12 Jan 2022 13:21:57 +0000 +Subject: [PATCH 2/3] x86: Add q35 RHEL 9.0.0 machine type + +RH-Author: Dr. David Alan Gilbert +RH-MergeRequest: 61: x86: Add rhel 8.6.0 & 9.0.0 machine types +RH-Commit: [2/2] 743378502459b978efd632271f97ddb824422203 (dagrh/c-9-s-qemu-kvm) +RH-Bugzilla: 1945666 +RH-Acked-by: Miroslav Rezanina +RH-Acked-by: Stefano Garzarella +RH-Acked-by: Cornelia Huck + +Add a rhel-9.0.0 q35 machine type; it's currently identical to 8.6.0; +but having a separate machine type will make life easier in the future +when the 8.x types go away. + +Note: The smbios stream product name has now changed to 'RHEL' + +bz: https://bugzilla.redhat.com/show_bug.cgi?id=1945666 +Signed-off-by: Dr. David Alan Gilbert +--- + hw/i386/pc_q35.c | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c +index 0c25305f15..bf9ad32f0e 100644 +--- a/hw/i386/pc_q35.c ++++ b/hw/i386/pc_q35.c +@@ -646,6 +646,23 @@ static void pc_q35_machine_rhel_options(MachineClass *m) + compat_props_add(m->compat_props, pc_rhel_compat, pc_rhel_compat_len); + } + ++static void pc_q35_init_rhel900(MachineState *machine) ++{ ++ pc_q35_init(machine); ++} ++ ++static void pc_q35_machine_rhel900_options(MachineClass *m) ++{ ++ PCMachineClass *pcmc = PC_MACHINE_CLASS(m); ++ pc_q35_machine_rhel_options(m); ++ m->desc = "RHEL-9.0.0 PC (Q35 + ICH9, 2009)"; ++ pcmc->smbios_stream_product = "RHEL"; ++ pcmc->smbios_stream_version = "9.0.0"; ++} ++ ++DEFINE_PC_MACHINE(q35_rhel900, "pc-q35-rhel9.0.0", pc_q35_init_rhel900, ++ pc_q35_machine_rhel900_options); ++ + static void pc_q35_init_rhel860(MachineState *machine) + { + pc_q35_init(machine); +@@ -654,8 +671,9 @@ static void pc_q35_init_rhel860(MachineState *machine) + static void pc_q35_machine_rhel860_options(MachineClass *m) + { + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); +- pc_q35_machine_rhel_options(m); ++ pc_q35_machine_rhel900_options(m); + m->desc = "RHEL-8.6.0 PC (Q35 + ICH9, 2009)"; ++ m->alias = NULL; + pcmc->smbios_stream_product = "RHEL-AV"; + pcmc->smbios_stream_version = "8.6.0"; + } +@@ -674,7 +692,6 @@ static void pc_q35_machine_rhel850_options(MachineClass *m) + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + pc_q35_machine_rhel860_options(m); + m->desc = "RHEL-8.5.0 PC (Q35 + ICH9, 2009)"; +- m->alias = NULL; + pcmc->smbios_stream_product = "RHEL-AV"; + pcmc->smbios_stream_version = "8.5.0"; + compat_props_add(m->compat_props, hw_compat_rhel_8_5, +-- +2.27.0 + diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec index d35d448..c403f49 100644 --- a/SPECS/qemu-kvm.spec +++ b/SPECS/qemu-kvm.spec @@ -110,9 +110,23 @@ %global requires_all_modules \ %if %{have_opengl} \ Requires: %{name}-ui-opengl = %{epoch}:%{version}-%{release} \ +Requires: %{name}-ui-egl-headless = %{epoch}:%{version}-%{release} \ %endif \ +Requires: %{name}-device-display-virtio-gpu = %{epoch}:%{version}-%{release} \ +Requires: %{name}-device-display-virtio-gpu-gl = %{epoch}:%{version}-%{release} \ +%ifarch s390x \ +Requires: %{name}-device-display-virtio-gpu-ccw = %{epoch}:%{version}-%{release} \ +%else \ +Requires: %{name}-device-display-virtio-gpu-pci = %{epoch}:%{version}-%{release} \ +Requires: %{name}-device-display-virtio-gpu-pci-gl = %{epoch}:%{version}-%{release} \ +%endif \ +%ifarch x86_64 %{power64} \ +Requires: %{name}-device-display-virtio-vga = %{epoch}:%{version}-%{release} \ +Requires: %{name}-device-display-virtio-vga-gl = %{epoch}:%{version}-%{release} \ +%endif \ +Requires: %{name}-device-usb-host = %{epoch}:%{version}-%{release} \ %if %{have_usbredir} \ -Requires: %{name}-hw-usbredir = %{epoch}:%{version}-%{release} \ +Requires: %{name}-device-usb-redirect = %{epoch}:%{version}-%{release} \ %endif \ Requires: %{name}-block-rbd = %{epoch}:%{version}-%{release} \ Requires: %{name}-audio-pa = %{epoch}:%{version}-%{release} @@ -130,7 +144,7 @@ Obsoletes: %{name}-block-iscsi <= %{version} \ Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm Version: 6.2.0 -Release: 3%{?rcrel}%{?dist}%{?cc_suffix} +Release: 9%{?rcrel}%{?dist}%{?cc_suffix} # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped # Epoch 15 used for RHEL 8 # Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5) @@ -193,6 +207,68 @@ Patch31: kvm-hw-arm-virt-Expose-the-RAS-option.patch Patch32: kvm-hw-arm-virt-Add-9.0-machine-type-and-remove-8.5-one.patch # For bz#2031044 - Add rhel-9.0.0 machine types for RHEL 9.0 [aarch64] Patch33: kvm-hw-arm-virt-Check-no_tcg_its-and-minor-style-changes.patch +# For bz#2024544 - Fio workers hangs when running fio with 32 jobs iodepth 32 and QEMU's userspace NVMe driver +Patch34: kvm-block-nvme-fix-infinite-loop-in-nvme_free_req_queue_.patch +# For bz#2028623 - [9.0] machine types: 6.2: Fix prefer_sockets +Patch35: kvm-rhel-machine-types-x86-set-prefer_sockets.patch +# For bz#1945666 - 9.0: x86 machine types +Patch36: kvm-x86-Add-q35-RHEL-8.6.0-machine-type.patch +# For bz#1945666 - 9.0: x86 machine types +Patch37: kvm-x86-Add-q35-RHEL-9.0.0-machine-type.patch +# For bz#2036669 - DEVICE_DELETED event is not delivered for device frontend if -device is configured via JSON +Patch38: kvm-softmmu-fix-device-deletion-events-with-device-JSON-.patch +# For bz#1962088 - [QSD] wrong help message for the fuse +Patch39: kvm-qemu-storage-daemon-Add-vhost-user-blk-help.patch +# For bz#1962088 - [QSD] wrong help message for the fuse +Patch40: kvm-qemu-storage-daemon-Fix-typo-in-vhost-user-blk-help.patch +# For bz#2046201 - CVE-2022-0358 qemu-kvm: QEMU: virtiofsd: potential privilege escalation via CVE-2018-13405 [rhel-9.0] +Patch41: kvm-virtiofsd-Drop-membership-of-all-supplementary-group.patch +# For bz#2034791 - Booting from Local Snapshot Core Dumped Whose Backing File Is Based on RBD +Patch42: kvm-block-rbd-fix-handling-of-holes-in-.bdrv_co_block_st.patch +# For bz#2034791 - Booting from Local Snapshot Core Dumped Whose Backing File Is Based on RBD +Patch43: kvm-block-rbd-workaround-for-ceph-issue-53784.patch +# For bz#2033708 - [Intel 9.0 Feat] qemu-kvm: SGX 1.5 (SGX1 + Flexible Launch Control) support +Patch44: kvm-numa-Enable-numa-for-SGX-EPC-sections.patch +# For bz#2033708 - [Intel 9.0 Feat] qemu-kvm: SGX 1.5 (SGX1 + Flexible Launch Control) support +Patch45: kvm-numa-Support-SGX-numa-in-the-monitor-and-Libvirt-int.patch +# For bz#2033708 - [Intel 9.0 Feat] qemu-kvm: SGX 1.5 (SGX1 + Flexible Launch Control) support +Patch46: kvm-doc-Add-the-SGX-numa-description.patch +# For bz#2033708 - [Intel 9.0 Feat] qemu-kvm: SGX 1.5 (SGX1 + Flexible Launch Control) support +Patch47: kvm-Enable-SGX-RH-Only.patch +# For bz#2033708 - [Intel 9.0 Feat] qemu-kvm: SGX 1.5 (SGX1 + Flexible Launch Control) support +Patch48: kvm-qapi-Cleanup-SGX-related-comments-and-restore-sectio.patch +# For bz#2041461 - Inconsistent block status reply in qemu-nbd +Patch49: kvm-block-io-Update-BSC-only-if-want_zero-is-true.patch +# For bz#2041461 - Inconsistent block status reply in qemu-nbd +Patch50: kvm-iotests-block-status-cache-New-test.patch +# For bz#1882917 - the target image size is incorrect when converting a badly fragmented file +Patch51: kvm-iotests-Test-qemu-img-convert-of-zeroed-data-cluster.patch +# For bz#1882917 - the target image size is incorrect when converting a badly fragmented file +Patch52: kvm-qemu-img-make-is_allocated_sectors-more-efficient.patch +# For bz#2040123 - Qemu core dumped when do block-stream to a snapshot node on non-enough space storage +Patch53: kvm-block-backend-prevent-dangling-BDS-pointers-across-a.patch +# For bz#2040123 - Qemu core dumped when do block-stream to a snapshot node on non-enough space storage +Patch54: kvm-iotests-stream-error-on-reset-New-test.patch +# For bz#2042481 - [aarch64] Launch guest with "default-bus-bypass-iommu=off,iommu=smmuv3" and "iommu_platform=on", guest hangs after system_reset +Patch55: kvm-hw-arm-smmuv3-Fix-device-reset.patch +# For bz#2046659 - qemu crash after execute blockdev-reopen with iothread +Patch56: kvm-block-Lock-AioContext-for-drain_end-in-blockdev-reop.patch +# For bz#2046659 - qemu crash after execute blockdev-reopen with iothread +Patch57: kvm-iotests-Test-blockdev-reopen-with-iothreads-and-thro.patch +# For bz#2033626 - Qemu core dump when start guest with nbd node or do block jobs to nbd node +Patch58: kvm-block-nbd-Delete-reconnect-delay-timer-when-done.patch +# For bz#2033626 - Qemu core dump when start guest with nbd node or do block jobs to nbd node +Patch59: kvm-block-nbd-Assert-there-are-no-timers-when-closed.patch +# For bz#2033626 - Qemu core dump when start guest with nbd node or do block jobs to nbd node +Patch60: kvm-iotests.py-Add-QemuStorageDaemon-class.patch +# For bz#2033626 - Qemu core dump when start guest with nbd node or do block jobs to nbd node +Patch61: kvm-iotests-281-Test-lingering-timers.patch +# For bz#2033626 - Qemu core dump when start guest with nbd node or do block jobs to nbd node +Patch62: kvm-block-nbd-Move-s-ioc-on-AioContext-change.patch +# For bz#2033626 - Qemu core dump when start guest with nbd node or do block jobs to nbd node +Patch63: kvm-iotests-281-Let-NBD-connection-yield-in-iothread.patch + +# Source-git patches %if %{have_clang} BuildRequires: clang @@ -303,7 +379,15 @@ Requires: libfdt >= %{libfdt_version} emulation for the KVM hypervisor. %{name} acts as a virtual machine monitor together with the KVM kernel modules, and emulates the hardware for a full system such as a PC and its associated peripherals. - +This is a minimalistic installation of %{name}. Functionality provided by +this package is not ensured and it can change in a future version as some +functionality can be split out to separate package. +Before updating this package, it is recommended to check the package +changelog for information on functionality which might have been moved to +a separate package to prevent issues due to the moved functionality. +If apps opt-in to minimalist packaging by depending on %{name}-core, they +explicitly accept that features may disappear from %{name}-core in future +updates. %package common Summary: QEMU common files needed by all QEMU targets @@ -439,15 +523,76 @@ Requires: mesa-libEGL Requires: mesa-dri-drivers %description ui-opengl This package provides opengl support. + +%package ui-egl-headless +Summary: QEMU EGL headless driver +Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} +Requires: %{name}-ui-opengl%{?_isa} = %{epoch}:%{version}-%{release} +%description ui-egl-headless +This package provides the additional egl-headless UI for QEMU. +%endif + + +%package device-display-virtio-gpu +Summary: QEMU virtio-gpu display device +Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} +%description device-display-virtio-gpu +This package provides the virtio-gpu display device for QEMU. + +%package device-display-virtio-gpu-gl +Summary: QEMU virtio-gpu-gl display device +Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} +%description device-display-virtio-gpu-gl +This package provides the virtio-gpu-gl display device for QEMU. + +%ifarch s390x +%package device-display-virtio-gpu-ccw +Summary: QEMU virtio-gpu-ccw display device +Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} +%description device-display-virtio-gpu-ccw +This package provides the virtio-gpu-ccw display device for QEMU. +%else +%package device-display-virtio-gpu-pci +Summary: QEMU virtio-gpu-pci display device +Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} +%description device-display-virtio-gpu-pci +This package provides the virtio-gpu-pci display device for QEMU. + +%package device-display-virtio-gpu-pci-gl +Summary: QEMU virtio-gpu-pci-gl display device +Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} +%description device-display-virtio-gpu-pci-gl +This package provides the virtio-gpu-pci-gl display device for QEMU. +%endif + +%ifarch x86_64 %{power64} +%package device-display-virtio-vga +Summary: QEMU virtio-vga display device +Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} +%description device-display-virtio-vga +This package provides the virtio-vga display device for QEMU. + +%package device-display-virtio-vga-gl +Summary: QEMU virtio-vga-gl display device +Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} +%description device-display-virtio-vga-gl +This package provides the virtio-vga-gl display device for QEMU. %endif +%package device-usb-host +Summary: QEMU usb host device +Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} +%description device-usb-host +This package provides the USB pass through driver for QEMU. + %if %{have_usbredir} -%package hw-usbredir +%package device-usb-redirect Summary: QEMU usbredir support Requires: %{name}-common%{?_isa} = %{epoch}:%{version}-%{release} Requires: usbredir >= 0.7.1 +Provides: %{name}-hw-usbredir -%description hw-usbredir +%description device-usb-redirect This package provides usbredir support. %endif @@ -1105,9 +1250,6 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %{_datadir}/%{name}/s390-ccw.img %{_datadir}/%{name}/s390-netboot.img %endif -%ifnarch aarch64 s390x - %{_libdir}/%{name}/hw-display-virtio-vga.so -%endif %{_datadir}/icons/* %{_datadir}/%{name}/linuxboot_dma.bin %if %{have_modules_load} @@ -1125,25 +1267,33 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %{_datadir}/%{name}/systemtap/script.d/qemu_kvm.stp %{_datadir}/%{name}/systemtap/conf.d/qemu_kvm.conf +%ifarch x86_64 + %{_libdir}/%{name}/accel-tcg-%{kvm_target}.so +%endif + +%files device-display-virtio-gpu %{_libdir}/%{name}/hw-display-virtio-gpu.so +%files device-display-virtio-gpu-gl %{_libdir}/%{name}/hw-display-virtio-gpu-gl.so -%ifarch x86_64 %{power64} - %{_libdir}/%{name}/hw-display-virtio-vga-gl.so -%endif %ifarch s390x +%files device-display-virtio-gpu-ccw %{_libdir}/%{name}/hw-s390x-virtio-gpu-ccw.so %else +%files device-display-virtio-gpu-pci %{_libdir}/%{name}/hw-display-virtio-gpu-pci.so +%files device-display-virtio-gpu-pci-gl %{_libdir}/%{name}/hw-display-virtio-gpu-pci-gl.so %endif - %{_libdir}/%{name}/accel-qtest-%{kvm_target}.so -%ifarch x86_64 - %{_libdir}/%{name}/accel-tcg-%{kvm_target}.so +%ifarch x86_64 %{power64} +%files device-display-virtio-vga + %{_libdir}/%{name}/hw-display-virtio-vga.so +%files device-display-virtio-vga-gl + %{_libdir}/%{name}/hw-display-virtio-vga-gl.so %endif -%{_libdir}/%{name}/hw-usb-host.so %files tests %{testsdir} +%{_libdir}/%{name}/accel-qtest-%{kvm_target}.so %files block-curl %{_libdir}/%{name}/block-curl.so @@ -1158,12 +1308,16 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %if %{have_opengl} %files ui-opengl -%{_libdir}/%{name}/ui-egl-headless.so %{_libdir}/%{name}/ui-opengl.so +%files ui-egl-headless +%{_libdir}/%{name}/ui-egl-headless.so %endif +%files device-usb-host +%{_libdir}/%{name}/hw-usb-host.so + %if %{have_usbredir} -%files hw-usbredir +%files device-usb-redirect %{_libdir}/%{name}/hw-usb-redirect.so %endif @@ -1171,6 +1325,88 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Thu Feb 17 2022 Miroslav Rezanina - 6.2.0-9 +- kvm-block-Lock-AioContext-for-drain_end-in-blockdev-reop.patch [bz#2046659] +- kvm-iotests-Test-blockdev-reopen-with-iothreads-and-thro.patch [bz#2046659] +- kvm-block-nbd-Delete-reconnect-delay-timer-when-done.patch [bz#2033626] +- kvm-block-nbd-Assert-there-are-no-timers-when-closed.patch [bz#2033626] +- kvm-iotests.py-Add-QemuStorageDaemon-class.patch [bz#2033626] +- kvm-iotests-281-Test-lingering-timers.patch [bz#2033626] +- kvm-block-nbd-Move-s-ioc-on-AioContext-change.patch [bz#2033626] +- kvm-iotests-281-Let-NBD-connection-yield-in-iothread.patch [bz#2033626] +- Resolves: bz#2046659 + (qemu crash after execute blockdev-reopen with iothread) +- Resolves: bz#2033626 + (Qemu core dump when start guest with nbd node or do block jobs to nbd node) + +* Mon Feb 14 2022 Miroslav Rezanina - 6.2.0-8 +- kvm-numa-Enable-numa-for-SGX-EPC-sections.patch [bz#2033708] +- kvm-numa-Support-SGX-numa-in-the-monitor-and-Libvirt-int.patch [bz#2033708] +- kvm-doc-Add-the-SGX-numa-description.patch [bz#2033708] +- kvm-Enable-SGX-RH-Only.patch [bz#2033708] +- kvm-qapi-Cleanup-SGX-related-comments-and-restore-sectio.patch [bz#2033708] +- kvm-block-io-Update-BSC-only-if-want_zero-is-true.patch [bz#2041461] +- kvm-iotests-block-status-cache-New-test.patch [bz#2041461] +- kvm-iotests-Test-qemu-img-convert-of-zeroed-data-cluster.patch [bz#1882917] +- kvm-qemu-img-make-is_allocated_sectors-more-efficient.patch [bz#1882917] +- kvm-block-backend-prevent-dangling-BDS-pointers-across-a.patch [bz#2040123] +- kvm-iotests-stream-error-on-reset-New-test.patch [bz#2040123] +- kvm-hw-arm-smmuv3-Fix-device-reset.patch [bz#2042481] +- Resolves: bz#2033708 + ([Intel 9.0 Feat] qemu-kvm: SGX 1.5 (SGX1 + Flexible Launch Control) support) +- Resolves: bz#2041461 + (Inconsistent block status reply in qemu-nbd) +- Resolves: bz#1882917 + (the target image size is incorrect when converting a badly fragmented file) +- Resolves: bz#2040123 + (Qemu core dumped when do block-stream to a snapshot node on non-enough space storage) +- Resolves: bz#2042481 + ([aarch64] Launch guest with "default-bus-bypass-iommu=off,iommu=smmuv3" and "iommu_platform=on", guest hangs after system_reset) + +* Mon Feb 07 2022 Miroslav Rezanina - 6.2.0-7 +- kvm-qemu-storage-daemon-Add-vhost-user-blk-help.patch [bz#1962088] +- kvm-qemu-storage-daemon-Fix-typo-in-vhost-user-blk-help.patch [bz#1962088] +- kvm-virtiofsd-Drop-membership-of-all-supplementary-group.patch [bz#2046201] +- kvm-block-rbd-fix-handling-of-holes-in-.bdrv_co_block_st.patch [bz#2034791] +- kvm-block-rbd-workaround-for-ceph-issue-53784.patch [bz#2034791] +- Resolves: bz#1962088 + ([QSD] wrong help message for the fuse) +- Resolves: bz#2046201 + (CVE-2022-0358 qemu-kvm: QEMU: virtiofsd: potential privilege escalation via CVE-2018-13405 [rhel-9.0]) +- Resolves: bz#2034791 + (Booting from Local Snapshot Core Dumped Whose Backing File Is Based on RBD) + +* Wed Feb 02 2022 Miroslav Rezanina - 6.2.0-6 +- Moving feature support out of qemu-kvm-core to separate packages (can + cause loss of functionality when using only qemu-kvm-core - qemu-kvm keeps + same feature set). +- kvm-spec-Rename-qemu-kvm-hw-usbredir-to-qemu-kvm-device-.patch [bz#2022847] +- kvm-spec-Split-qemu-kvm-ui-opengl.patch [bz#2022847] +- kvm-spec-Introduce-packages-for-virtio-gpu-modules.patch [bz#2022847] +- kvm-spec-Introduce-device-display-virtio-vga-packages.patch [bz#2022847] +- kvm-spec-Move-usb-host-module-to-separate-package.patch [bz#2022847] +- kvm-spec-Move-qtest-accel-module-to-tests-package.patch [bz#2022847] +- kvm-spec-Extend-qemu-kvm-core-description.patch [bz#2022847] +- Resolves: bz#2022847 + (qemu-kvm: Align package split with Fedora) + +* Tue Jan 25 2022 Miroslav Rezanina - 6.2.0-5 +- kvm-x86-Add-q35-RHEL-8.6.0-machine-type.patch [bz#1945666] +- kvm-x86-Add-q35-RHEL-9.0.0-machine-type.patch [bz#1945666] +- kvm-softmmu-fix-device-deletion-events-with-device-JSON-.patch [bz#2036669] +- Resolves: bz#1945666 + (9.0: x86 machine types) +- Resolves: bz#2036669 + (DEVICE_DELETED event is not delivered for device frontend if -device is configured via JSON) + +* Mon Jan 17 2022 Miroslav Rezanina - 6.2.0-4 +- kvm-block-nvme-fix-infinite-loop-in-nvme_free_req_queue_.patch [bz#2024544] +- kvm-rhel-machine-types-x86-set-prefer_sockets.patch [bz#2028623] +- Resolves: bz#2024544 + (Fio workers hangs when running fio with 32 jobs iodepth 32 and QEMU's userspace NVMe driver) +- Resolves: bz#2028623 + ([9.0] machine types: 6.2: Fix prefer_sockets) + * Mon Jan 10 2022 Miroslav Rezanina - 6.2.0-3 - kvm-hw-arm-virt-Register-iommu-as-a-class-property.patch [bz#2031044] - kvm-hw-arm-virt-Register-its-as-a-class-property.patch [bz#2031044]