By default, the host adapter instance expects the maximum of 8 LUNs. The virtio-scsi driver doesn't override this value, as it queries for the actual number of the Logical Units during virtscsi_probe(). Still, some drivers do not perform such scan and assume the virtio_scsi_scsi_info.max_lun value to be definite and correct, which might not be true. This can result in the driver queuing up SCSI commands referring to LUNs that do not exist.
Add "max_lun" option to virtio-scsi and vhost-scsi devices to specify the maximum number of LUNs to prevent sending commands to Logical Units that do not exist. Signed-off-by: Karolina Stolarek <[email protected]> --- hw/scsi/vhost-scsi.c | 2 ++ hw/scsi/virtio-scsi.c | 6 ++++-- include/hw/virtio/virtio-scsi.h | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index 1a4860a72f..6883629170 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -355,6 +355,8 @@ static const Property vhost_scsi_properties[] = { true), DEFINE_PROP_UINT16("max_target", VirtIOSCSICommon, conf.max_target, VIRTIO_SCSI_MAX_TARGET), + DEFINE_PROP_UINT32("max_lun", VirtIOSCSICommon, conf.max_lun, + VIRTIO_SCSI_MAX_LUN), DEFINE_PROP_UINT32("max_sectors", VirtIOSCSICommon, conf.max_sectors, 0xFFFF), DEFINE_PROP_UINT32("cmd_per_lun", VirtIOSCSICommon, conf.cmd_per_lun, 128), diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 091f68090e..9e7eebd835 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -972,7 +972,7 @@ static void virtio_scsi_get_config(VirtIODevice *vdev, virtio_stl_p(vdev, &scsiconf->cdb_size, s->cdb_size); virtio_stw_p(vdev, &scsiconf->max_channel, VIRTIO_SCSI_MAX_CHANNEL); virtio_stw_p(vdev, &scsiconf->max_target, s->conf.max_target); - virtio_stl_p(vdev, &scsiconf->max_lun, VIRTIO_SCSI_MAX_LUN); + virtio_stl_p(vdev, &scsiconf->max_lun, s->conf.max_lun); } static void virtio_scsi_set_config(VirtIODevice *vdev, @@ -1266,7 +1266,7 @@ static void virtio_scsi_init_scsi_info(struct VirtIOSCSIConf *conf) { virtio_scsi_scsi_info.tcq = true; virtio_scsi_scsi_info.max_channel = VIRTIO_SCSI_MAX_CHANNEL; - virtio_scsi_scsi_info.max_lun = VIRTIO_SCSI_MAX_LUN; + virtio_scsi_scsi_info.max_lun = conf->max_lun; virtio_scsi_scsi_info.max_target = conf->max_target; virtio_scsi_scsi_info.complete = virtio_scsi_command_complete; @@ -1385,6 +1385,8 @@ static const Property virtio_scsi_properties[] = { parent_obj.conf.seg_max_adjust, true), DEFINE_PROP_UINT16("max_target", VirtIOSCSICommon, conf.max_target, VIRTIO_SCSI_MAX_TARGET), + DEFINE_PROP_UINT32("max_lun", VirtIOSCSICommon, conf.max_lun, + VIRTIO_SCSI_MAX_LUN), DEFINE_PROP_UINT32("max_sectors", VirtIOSCSI, parent_obj.conf.max_sectors, 0xFFFF), DEFINE_PROP_UINT32("cmd_per_lun", VirtIOSCSI, parent_obj.conf.cmd_per_lun, diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index 3998b241f6..61fe5cae34 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -55,6 +55,7 @@ struct VirtIOSCSIConf { bool worker_per_virtqueue; bool seg_max_adjust; uint16_t max_target; + uint32_t max_lun; uint32_t max_sectors; uint32_t cmd_per_lun; char *vhostfd; -- 2.47.1
