From what I understand the LUN is a 14 bit field so VIRTIO_SCSI_MAX_LUN should be enforced. Should this code check that max_lun is valid and clamp and print a warning if it isn't?

Otherwise looks good to me.

On 5/4/26 9:59 AM, Karolina Stolarek wrote:
The virtio-scsi driver in the guest is able to retrieve
the correct number of LUNs by querying REPORT_LUNS. There
are some drivers, such as OVMF VirtioScsiDxe, that discover
LUNs by queuing INQUIRY commands up to an arbitrary limit.

This is an issue for vhost-scsi devices, as each inquiry
to a LUN in a target that exists causes "Detected
NON_EXISTENT_LUN Access" errors to flood the kernel logs
of the hypervisor during VM boot.

Add a "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 don't exist.

Cc: Stefano Garzarella <[email protected]>
Cc: Raphael Norwitz <[email protected]>
Signed-off-by: Karolina Stolarek <[email protected]>
---
  hw/scsi/vhost-scsi.c            | 2 ++
  hw/scsi/vhost-user-scsi.c       | 2 ++
  hw/scsi/virtio-scsi.c           | 6 ++++--
  include/hw/virtio/virtio-scsi.h | 1 +
  4 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index b2e8240344..568ce02e36 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -354,6 +354,8 @@ static const Property vhost_scsi_properties[] = {
                        true),
      DEFINE_PROP_UINT8("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/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index 4e59f06ea2..f4c761bf18 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -354,6 +354,8 @@ static const Property vhost_user_scsi_properties[] = {
                         128),
      DEFINE_PROP_UINT8("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 4de06bad3d..3a10ef2118 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -976,7 +976,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,
@@ -1324,7 +1324,7 @@ static void virtio_scsi_scsi_config_init(VirtIOSCSI *s)
      s->bus_config->tcq = true;
      s->bus_config->max_channel = VIRTIO_SCSI_MAX_CHANNEL;
      s->bus_config->max_target = s->parent_obj.conf.max_target;
-    s->bus_config->max_lun = VIRTIO_SCSI_MAX_LUN;
+    s->bus_config->max_lun = s->parent_obj.conf.max_lun;
  }
static void virtio_scsi_scsi_bus_cleanup(VirtIOSCSI *s)
@@ -1404,6 +1404,8 @@ static const Property virtio_scsi_properties[] = {
                        parent_obj.conf.seg_max_adjust, true),
      DEFINE_PROP_UINT8("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 b4b796fc58..9d5b90c3bc 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;
      uint8_t max_target;
+    uint32_t max_lun;
      uint32_t max_sectors;
      uint32_t cmd_per_lun;
      char *vhostfd;


Reply via email to