[PATCH] block: switch to co_wrapper_mixed for blk_lock_medium() and blk_eject()

Boudewijn van der Heide posted 1 patch 1 week, 1 day ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260530175822.10321-1-boudewijn@delta-utec.com
Maintainers: Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>
include/system/block-backend-io.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
[PATCH] block: switch to co_wrapper_mixed for blk_lock_medium() and blk_eject()
Posted by Boudewijn van der Heide 1 week, 1 day ago
scsi_disk_emulate_command() can be called from a coroutine;
when req->cmd.buf[0] is ALLOW_MEDIUM_REMOVAL, the synchronous
blk_lock_medium() is called, which hits assert(!qemu_in_coroutine()),
and crashes:

	qemu-system-hppa: block/block-gen.c:1692: blk_lock_medium:
	Assertion `!qemu_in_coroutine()' failed.

blk_eject() has the same problem, it can be called from coroutine,
because the same vtable entry (SCSIReqOps.send_command,
scsi_disk_emulate_command() here) calls blk_eject when req->cmd.buf[0]
is START_STOP.

Fix by switching to co_wrapper_mixed for blk_lock_medium() and
blk_eject() instead of just co_wrapper.

Signed-off-by: Boudewijn van der Heide <boudewijn@delta-utec.com>
---
Observed crash on fedora qemu-10.1.5-1.fc43 on x86_64 host using qemu-system-hppa.

trace:

Thread 1 (...):
        # 5 __assert_fail (...) at assert.c
        # 6 blk_lock_medium (...) at block/block-gen.c
        # 7 scsi_disk_emulate_command (...) at ../hw/scsi/scsi-disk.c
        # 8 scsi_req_enqueue (...) at ../hw/scsi/scsi-bus.c
        # 9 lsi_do_command (...) at ../hw/scsi/lsi53c895a.c
        # 10 lsi_execute_script (...) at ../hw/scsi/lsi53c895a.c
        # 11 scsi_read_complete_noio (...) at ../hw/scsi/scsi-disk.c
        # 12 blk_aio_complete (...) at ../block/block-backend.c
        # 14 blk_aio_read_entry (...) at ../block/block-backend.c
        # 15 in coroutine_trampoline (...) at ../util/coroutine-ucontext.c

blk_eject() has the same path, but req->cmd.buf[0] is START_STOP instead
of ALLOW_MEDIUM_REMOVAL inside scsi_disk_emulate_command(),
so fix that aswell.
---
 include/system/block-backend-io.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/system/block-backend-io.h b/include/system/block-backend-io.h
index fd84723d9d..7368ad5c09 100644
--- a/include/system/block-backend-io.h
+++ b/include/system/block-backend-io.h
@@ -81,10 +81,10 @@ bool coroutine_fn GRAPH_RDLOCK blk_co_is_available(BlockBackend *blk);
 bool co_wrapper_mixed_bdrv_rdlock blk_is_available(BlockBackend *blk);
 
 void coroutine_fn blk_co_lock_medium(BlockBackend *blk, bool locked);
-void co_wrapper blk_lock_medium(BlockBackend *blk, bool locked);
+void co_wrapper_mixed blk_lock_medium(BlockBackend *blk, bool locked);
 
 void coroutine_fn blk_co_eject(BlockBackend *blk, bool eject_flag);
-void co_wrapper blk_eject(BlockBackend *blk, bool eject_flag);
+void co_wrapper_mixed blk_eject(BlockBackend *blk, bool eject_flag);
 
 int64_t coroutine_fn blk_co_getlength(BlockBackend *blk);
 int64_t co_wrapper_mixed blk_getlength(BlockBackend *blk);
-- 
2.54.0