From e0999eaacc6e74f5e56f51fcf3b3d7aeca7d3b04 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 6 Jun 2019 19:15:23 +0100 Subject: [PATCH 6/7] scsi-disk: Acquire the AioContext in scsi_*_realize() RH-Author: Markus Armbruster Message-id: <20190606191524.30797-3-armbru@redhat.com> Patchwork-id: 88605 O-Subject: [RHEL-8.1.0 qemu-kvm PATCH 2/3] scsi-disk: Acquire the AioContext in scsi_*_realize() Bugzilla: 1718992 RH-Acked-by: Paolo Bonzini RH-Acked-by: Stefan Hajnoczi RH-Acked-by: Kevin Wolf From: Alberto Garcia This fixes a crash when attaching two disks with the same blockdev to a SCSI device that is using iothreads. Test case included. Signed-off-by: Alberto Garcia Signed-off-by: Kevin Wolf (cherry picked from commit 3ff35ba391134e4e43ab96152deb38a62e62f858) [Trivial conflict in hw/scsi/scsi-disk.c due to lack of commit 51f43d5792e resolved] Signed-off-by: Markus Armbruster Signed-off-by: Danilo C. L. de Paula --- hw/scsi/scsi-disk.c | 23 ++++++++++++++++++++--- tests/qemu-iotests/240 | 18 ++++++++++++++++++ tests/qemu-iotests/240.out | 16 ++++++++++++++++ 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index a20ef91..08da23d 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -2378,10 +2378,13 @@ static void scsi_realize(SCSIDevice *dev, Error **errp) static void scsi_hd_realize(SCSIDevice *dev, Error **errp) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); + AioContext *ctx = NULL; /* can happen for devices without drive. The error message for missing * backend will be issued in scsi_realize */ if (s->qdev.conf.blk) { + ctx = blk_get_aio_context(s->qdev.conf.blk); + aio_context_acquire(ctx); blkconf_blocksizes(&s->qdev.conf); } s->qdev.blocksize = s->qdev.conf.logical_block_size; @@ -2390,11 +2393,15 @@ static void scsi_hd_realize(SCSIDevice *dev, Error **errp) s->product = g_strdup("QEMU HARDDISK"); } scsi_realize(&s->qdev, errp); + if (ctx) { + aio_context_release(ctx); + } } static void scsi_cd_realize(SCSIDevice *dev, Error **errp) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); + AioContext *ctx; int ret; if (!dev->conf.blk) { @@ -2405,6 +2412,8 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp) assert(ret == 0); } + ctx = blk_get_aio_context(dev->conf.blk); + aio_context_acquire(ctx); s->qdev.blocksize = 2048; s->qdev.type = TYPE_ROM; s->features |= 1 << SCSI_DISK_F_REMOVABLE; @@ -2412,6 +2421,7 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp) s->product = g_strdup("QEMU CD-ROM"); } scsi_realize(&s->qdev, errp); + aio_context_release(ctx); } static void scsi_disk_realize(SCSIDevice *dev, Error **errp) @@ -2550,6 +2560,7 @@ static int get_device_type(SCSIDiskState *s) static void scsi_block_realize(SCSIDevice *dev, Error **errp) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); + AioContext *ctx; int sg_version; int rc; @@ -2558,6 +2569,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp) return; } + ctx = blk_get_aio_context(s->qdev.conf.blk); + aio_context_acquire(ctx); + /* check we are using a driver managing SG_IO (version 3 and after) */ rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version); if (rc < 0) { @@ -2565,18 +2579,18 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp) if (rc != -EPERM) { error_append_hint(errp, "Is this a SCSI device?\n"); } - return; + goto out; } if (sg_version < 30000) { error_setg(errp, "scsi generic interface too old"); - return; + goto out; } /* get device type from INQUIRY data */ rc = get_device_type(s); if (rc < 0) { error_setg(errp, "INQUIRY failed"); - return; + goto out; } /* Make a guess for the block size, we'll fix it when the guest sends. @@ -2596,6 +2610,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp) scsi_realize(&s->qdev, errp); scsi_generic_read_device_inquiry(&s->qdev); + +out: + aio_context_release(ctx); } typedef struct SCSIBlockReq { diff --git a/tests/qemu-iotests/240 b/tests/qemu-iotests/240 index ead7ee0..5d499c9 100755 --- a/tests/qemu-iotests/240 +++ b/tests/qemu-iotests/240 @@ -83,6 +83,24 @@ run_qemu <