Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 30683a8c authored by Michael S. Tsirkin's avatar Michael S. Tsirkin
Browse files

virtio: set VIRTIO_CONFIG_S_FEATURES_OK on restore



virtio 1.0 devices require that drivers set VIRTIO_CONFIG_S_FEATURES_OK
after finalizing features.
virtio core missed doing this on restore, fix it up.

Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Reviewed-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
parent f01a2a81
Loading
Loading
Loading
Loading
+23 −14
Original line number Diff line number Diff line
@@ -162,6 +162,27 @@ static void virtio_config_enable(struct virtio_device *dev)
	spin_unlock_irq(&dev->config_lock);
}

static int virtio_finalize_features(struct virtio_device *dev)
{
	int ret = dev->config->finalize_features(dev);
	unsigned status;

	if (ret)
		return ret;

	if (!virtio_has_feature(dev, VIRTIO_F_VERSION_1))
		return 0;

	add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
	status = dev->config->get_status(dev);
	if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) {
		dev_err(&dev->dev, "virtio: device refuses features: %x\n",
			status);
		return -ENODEV;
	}
	return 0;
}

static int virtio_dev_probe(struct device *_d)
{
	int err, i;
@@ -170,7 +191,6 @@ static int virtio_dev_probe(struct device *_d)
	u64 device_features;
	u64 driver_features;
	u64 driver_features_legacy;
	unsigned status;

	/* We have a driver! */
	add_status(dev, VIRTIO_CONFIG_S_DRIVER);
@@ -208,21 +228,10 @@ static int virtio_dev_probe(struct device *_d)
		if (device_features & (1ULL << i))
			__virtio_set_bit(dev, i);

	err = dev->config->finalize_features(dev);
	err = virtio_finalize_features(dev);
	if (err)
		goto err;

	if (virtio_has_feature(dev, VIRTIO_F_VERSION_1)) {
		add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
		status = dev->config->get_status(dev);
		if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) {
			dev_err(_d, "virtio: device refuses features: %x\n",
			       status);
			err = -ENODEV;
			goto err;
		}
	}

	err = drv->probe(dev);
	if (err)
		goto err;
@@ -372,7 +381,7 @@ int virtio_device_restore(struct virtio_device *dev)
	/* We have a driver! */
	add_status(dev, VIRTIO_CONFIG_S_DRIVER);

	ret = dev->config->finalize_features(dev);
	ret = virtio_finalize_features(dev);
	if (ret)
		goto err;