diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2014-10-15 01:52:31 +0200 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2014-10-15 01:55:06 +0200 |
commit | cd679048958011418f14a8fc7dfdb64ab72ca315 (patch) | |
tree | b51cf102430d9f6cf74e8266a54f75aae010cde4 /drivers/scsi/virtio_scsi.c | |
parent | virtio_net: fix use after free on allocation failure (diff) | |
download | linux-cd679048958011418f14a8fc7dfdb64ab72ca315.tar.xz linux-cd679048958011418f14a8fc7dfdb64ab72ca315.zip |
virtio_scsi: move kick event out from virtscsi_init
We currently kick event within virtscsi_init,
before host is fully initialized.
This can in theory confuse guest if device
consumes the buffers immediately.
To fix, move virtscsi_kick_event_all out to scan/restore.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/scsi/virtio_scsi.c')
-rw-r--r-- | drivers/scsi/virtio_scsi.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index eee1bc0b506e..0642ce387c75 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -853,7 +853,11 @@ static void virtscsi_init_vq(struct virtio_scsi_vq *virtscsi_vq, static void virtscsi_scan(struct virtio_device *vdev) { - struct Scsi_Host *shost = (struct Scsi_Host *)vdev->priv; + struct Scsi_Host *shost = virtio_scsi_host(vdev); + struct virtio_scsi *vscsi = shost_priv(shost); + + if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) + virtscsi_kick_event_all(vscsi); scsi_scan_host(shost); } @@ -916,9 +920,6 @@ static int virtscsi_init(struct virtio_device *vdev, virtscsi_config_set(vdev, cdb_size, VIRTIO_SCSI_CDB_SIZE); virtscsi_config_set(vdev, sense_size, VIRTIO_SCSI_SENSE_SIZE); - if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) - virtscsi_kick_event_all(vscsi); - err = 0; out: @@ -1048,8 +1049,13 @@ static int virtscsi_restore(struct virtio_device *vdev) return err; err = register_hotcpu_notifier(&vscsi->nb); - if (err) + if (err) { vdev->config->del_vqs(vdev); + return err; + } + + if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) + virtscsi_kick_event_all(vscsi); return err; } |