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


Reply via email to