Commit 941e3e79 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull virtio fixes from Michael Tsirkin:
 "Fixes all over the place, most notably we are disabling
  IRQ hardening (again!)"

* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
  virtio_ring: make vring_create_virtqueue_split prettier
  vhost-vdpa: call vhost_vdpa_cleanup during the release
  virtio_mmio: Restore guest page size on resume
  virtio_mmio: Add missing PM calls to freeze/restore
  caif_virtio: fix race between virtio_device_ready() and ndo_open()
  virtio-net: fix race between ndo_open() and virtio_device_ready()
  virtio: disable notification hardening by default
  virtio: Remove unnecessary variable assignments
  virtio_ring : keep used_wrap_counter in vq->last_used_idx
  vduse: Tie vduse mgmtdev and its device
  vdpa/mlx5: Initialize CVQ vringh only once
  vdpa/mlx5: Update Control VQ callback information
parents 23900951 c7cc29aa
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -722,13 +722,21 @@ static int cfv_probe(struct virtio_device *vdev)
	/* Carrier is off until netdevice is opened */
	netif_carrier_off(netdev);

	/* serialize netdev register + virtio_device_ready() with ndo_open() */
	rtnl_lock();

	/* register Netdev */
	err = register_netdev(netdev);
	err = register_netdevice(netdev);
	if (err) {
		rtnl_unlock();
		dev_err(&vdev->dev, "Unable to register netdev (%d)\n", err);
		goto err;
	}

	virtio_device_ready(vdev);

	rtnl_unlock();

	debugfs_init(cfv);

	return 0;
+7 −1
Original line number Diff line number Diff line
@@ -3642,14 +3642,20 @@ static int virtnet_probe(struct virtio_device *vdev)
	if (vi->has_rss || vi->has_rss_hash_report)
		virtnet_init_default_rss(vi);

	err = register_netdev(dev);
	/* serialize netdev register + virtio_device_ready() with ndo_open() */
	rtnl_lock();

	err = register_netdevice(dev);
	if (err) {
		pr_debug("virtio_net: registering device failed\n");
		rtnl_unlock();
		goto free_failover;
	}

	virtio_device_ready(vdev);

	rtnl_unlock();

	err = virtnet_cpu_notif_add(vi);
	if (err) {
		pr_debug("virtio_net: registering cpu notifier failed\n");
+8 −1
Original line number Diff line number Diff line
@@ -1136,8 +1136,13 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev,
			vcdev->err = -EIO;
	}
	virtio_ccw_check_activity(vcdev, activity);
	/* Interrupts are disabled here */
#ifdef CONFIG_VIRTIO_HARDEN_NOTIFICATION
	/*
	 * Paired with virtio_ccw_synchronize_cbs() and interrupts are
	 * disabled here.
	 */
	read_lock(&vcdev->irq_lock);
#endif
	for_each_set_bit(i, indicators(vcdev),
			 sizeof(*indicators(vcdev)) * BITS_PER_BYTE) {
		/* The bit clear must happen before the vring kick. */
@@ -1146,7 +1151,9 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev,
		vq = virtio_ccw_vq_by_ind(vcdev, i);
		vring_interrupt(0, vq);
	}
#ifdef CONFIG_VIRTIO_HARDEN_NOTIFICATION
	read_unlock(&vcdev->irq_lock);
#endif
	if (test_bit(0, indicators2(vcdev))) {
		virtio_config_changed(&vcdev->vdev);
		clear_bit(0, indicators2(vcdev));
+22 −11
Original line number Diff line number Diff line
@@ -1962,6 +1962,8 @@ static void mlx5_vdpa_set_vq_cb(struct vdpa_device *vdev, u16 idx, struct vdpa_c
	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);

	ndev->event_cbs[idx] = *cb;
	if (is_ctrl_vq_idx(mvdev, idx))
		mvdev->cvq.event_cb = *cb;
}

static void mlx5_cvq_notify(struct vringh *vring)
@@ -2174,7 +2176,6 @@ static int verify_driver_features(struct mlx5_vdpa_dev *mvdev, u64 features)
static int setup_virtqueues(struct mlx5_vdpa_dev *mvdev)
{
	struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
	struct mlx5_control_vq *cvq = &mvdev->cvq;
	int err;
	int i;

@@ -2184,16 +2185,6 @@ static int setup_virtqueues(struct mlx5_vdpa_dev *mvdev)
			goto err_vq;
	}

	if (mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ)) {
		err = vringh_init_iotlb(&cvq->vring, mvdev->actual_features,
					MLX5_CVQ_MAX_ENT, false,
					(struct vring_desc *)(uintptr_t)cvq->desc_addr,
					(struct vring_avail *)(uintptr_t)cvq->driver_addr,
					(struct vring_used *)(uintptr_t)cvq->device_addr);
		if (err)
			goto err_vq;
	}

	return 0;

err_vq:
@@ -2466,6 +2457,21 @@ static void clear_vqs_ready(struct mlx5_vdpa_net *ndev)
	ndev->mvdev.cvq.ready = false;
}

static int setup_cvq_vring(struct mlx5_vdpa_dev *mvdev)
{
	struct mlx5_control_vq *cvq = &mvdev->cvq;
	int err = 0;

	if (mvdev->actual_features & BIT_ULL(VIRTIO_NET_F_CTRL_VQ))
		err = vringh_init_iotlb(&cvq->vring, mvdev->actual_features,
					MLX5_CVQ_MAX_ENT, false,
					(struct vring_desc *)(uintptr_t)cvq->desc_addr,
					(struct vring_avail *)(uintptr_t)cvq->driver_addr,
					(struct vring_used *)(uintptr_t)cvq->device_addr);

	return err;
}

static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)
{
	struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
@@ -2478,6 +2484,11 @@ static void mlx5_vdpa_set_status(struct vdpa_device *vdev, u8 status)

	if ((status ^ ndev->mvdev.status) & VIRTIO_CONFIG_S_DRIVER_OK) {
		if (status & VIRTIO_CONFIG_S_DRIVER_OK) {
			err = setup_cvq_vring(mvdev);
			if (err) {
				mlx5_vdpa_warn(mvdev, "failed to setup control VQ vring\n");
				goto err_setup;
			}
			err = setup_driver(mvdev);
			if (err) {
				mlx5_vdpa_warn(mvdev, "failed to setup driver\n");
+37 −23
Original line number Diff line number Diff line
@@ -1476,16 +1476,12 @@ static char *vduse_devnode(struct device *dev, umode_t *mode)
	return kasprintf(GFP_KERNEL, "vduse/%s", dev_name(dev));
}

static void vduse_mgmtdev_release(struct device *dev)
{
}

static struct device vduse_mgmtdev = {
	.init_name = "vduse",
	.release = vduse_mgmtdev_release,
struct vduse_mgmt_dev {
	struct vdpa_mgmt_dev mgmt_dev;
	struct device dev;
};

static struct vdpa_mgmt_dev mgmt_dev;
static struct vduse_mgmt_dev *vduse_mgmt;

static int vduse_dev_init_vdpa(struct vduse_dev *dev, const char *name)
{
@@ -1510,7 +1506,7 @@ static int vduse_dev_init_vdpa(struct vduse_dev *dev, const char *name)
	}
	set_dma_ops(&vdev->vdpa.dev, &vduse_dev_dma_ops);
	vdev->vdpa.dma_dev = &vdev->vdpa.dev;
	vdev->vdpa.mdev = &mgmt_dev;
	vdev->vdpa.mdev = &vduse_mgmt->mgmt_dev;

	return 0;
}
@@ -1556,34 +1552,52 @@ static struct virtio_device_id id_table[] = {
	{ 0 },
};

static struct vdpa_mgmt_dev mgmt_dev = {
	.device = &vduse_mgmtdev,
	.id_table = id_table,
	.ops = &vdpa_dev_mgmtdev_ops,
};
static void vduse_mgmtdev_release(struct device *dev)
{
	struct vduse_mgmt_dev *mgmt_dev;

	mgmt_dev = container_of(dev, struct vduse_mgmt_dev, dev);
	kfree(mgmt_dev);
}

static int vduse_mgmtdev_init(void)
{
	int ret;

	ret = device_register(&vduse_mgmtdev);
	if (ret)
	vduse_mgmt = kzalloc(sizeof(*vduse_mgmt), GFP_KERNEL);
	if (!vduse_mgmt)
		return -ENOMEM;

	ret = dev_set_name(&vduse_mgmt->dev, "vduse");
	if (ret) {
		kfree(vduse_mgmt);
		return ret;
	}

	ret = vdpa_mgmtdev_register(&mgmt_dev);
	vduse_mgmt->dev.release = vduse_mgmtdev_release;

	ret = device_register(&vduse_mgmt->dev);
	if (ret)
		goto err;
		goto dev_reg_err;

	return 0;
err:
	device_unregister(&vduse_mgmtdev);
	vduse_mgmt->mgmt_dev.id_table = id_table;
	vduse_mgmt->mgmt_dev.ops = &vdpa_dev_mgmtdev_ops;
	vduse_mgmt->mgmt_dev.device = &vduse_mgmt->dev;
	ret = vdpa_mgmtdev_register(&vduse_mgmt->mgmt_dev);
	if (ret)
		device_unregister(&vduse_mgmt->dev);

	return ret;

dev_reg_err:
	put_device(&vduse_mgmt->dev);
	return ret;
}

static void vduse_mgmtdev_exit(void)
{
	vdpa_mgmtdev_unregister(&mgmt_dev);
	device_unregister(&vduse_mgmtdev);
	vdpa_mgmtdev_unregister(&vduse_mgmt->mgmt_dev);
	device_unregister(&vduse_mgmt->dev);
}

static int vduse_init(void)
Loading