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;