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