@@ -128,6 +128,28 @@ static void vhost_scsi_stop(VHostSCSI *vs, VirtIODevice *vdev)
vhost_dev_disable_notifiers(&vs->dev, vdev);
}
+static uint32_t vhost_scsi_get_features(VirtIODevice *vdev,
+ uint32_t features)
+{
+ VHostSCSI *vs = (VHostSCSI *)vdev;
+
+ /* Clear features not supported by host kernel. */
+ if (!(vs->dev.features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY))) {
+ features &= ~(1 << VIRTIO_F_NOTIFY_ON_EMPTY);
+ }
+ if (!(vs->dev.features & (1 << VIRTIO_RING_F_INDIRECT_DESC))) {
+ features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC);
+ }
+ if (!(vs->dev.features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
+ features &= ~(1 << VIRTIO_RING_F_EVENT_IDX);
+ }
+ if (!(vs->dev.features & (1 << VIRTIO_SCSI_F_HOTPLUG))) {
+ features &= ~(1 << VIRTIO_SCSI_F_HOTPLUG);
+ }
+
+ return features;
+}
+
static void vhost_scsi_set_config(VirtIODevice *vdev,
const uint8_t *config)
{
@@ -203,6 +225,7 @@ VirtIODevice *vhost_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf)
vs = (VHostSCSI *)virtio_scsi_init_common(dev, proxyconf,
sizeof(VHostSCSI));
+ vs->vs.vdev.get_features = vhost_scsi_get_features;
vs->vs.vdev.set_config = vhost_scsi_set_config;
vs->vs.vdev.set_status = vhost_scsi_set_status;
vs->vs.vdev.guest_notifier_mask = vhost_scsi_guest_notifier_mask;
@@ -219,7 +242,7 @@ VirtIODevice *vhost_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf)
return NULL;
}
vs->dev.backend_features = 0;
- vs->dev.acked_features = 0;
+ vs->dev.acked_features = vs->dev.features;
error_setg(&vs->migration_blocker,
"vhost-scsi does not support migration");
@@ -50,14 +50,12 @@ enum vhost_scsi_vq_list {
#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, int)
#define DEFINE_VHOST_SCSI_PROPERTIES(_state, _features_field, _conf_field) \
- DEFINE_PROP_BIT("indirect_desc", _state, _features_field, VIRTIO_RING_F_INDIRECT_DESC, true), \
- DEFINE_PROP_BIT("event_idx", _state, _features_field, VIRTIO_RING_F_EVENT_IDX, false), \
+ DEFINE_VIRTIO_COMMON_FEATURES(_state, _features_field), \
DEFINE_PROP_STRING("vhostfd", _state, _conf_field.vhostfd), \
DEFINE_PROP_STRING("wwpn", _state, _conf_field.wwpn), \
DEFINE_PROP_UINT32("num_queues", _state, _conf_field.num_queues, 1), \
DEFINE_PROP_UINT32("max_sectors", _state, _conf_field.max_sectors, 0xFFFF), \
- DEFINE_PROP_UINT32("cmd_per_lun", _state, _conf_field.cmd_per_lun, 128), \
- DEFINE_PROP_BIT("hotplug", _state, _features_field, VIRTIO_SCSI_F_HOTPLUG, true)
+ DEFINE_PROP_UINT32("cmd_per_lun", _state, _conf_field.cmd_per_lun, 128)
VirtIODevice *vhost_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf);
void vhost_scsi_exit(VirtIODevice *vdev);
@@ -595,7 +595,6 @@ VirtIOSCSICommon *virtio_scsi_init_common(DeviceState *dev, VirtIOSCSIConf *prox
s->cdb_size = VIRTIO_SCSI_CDB_SIZE;
s->vdev.get_config = virtio_scsi_get_config;
- s->vdev.get_features = virtio_scsi_get_features;
s->ctrl_vq = virtio_add_queue(&s->vdev, VIRTIO_SCSI_VQ_SIZE,
virtio_scsi_handle_ctrl);
@@ -618,6 +617,7 @@ VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf)
s = (VirtIOSCSI *)virtio_scsi_init_common(dev, proxyconf, sizeof(VirtIOSCSI));
+ s->vs.vdev.get_features = virtio_scsi_get_features;
s->vs.vdev.set_config = virtio_scsi_set_config;
s->vs.vdev.reset = virtio_scsi_reset;