Commit 1eb8df18 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull virtio,vhost,vdpa updates from Michael Tsirkin:

 - Doorbell remapping for ifcvf, mlx5

 - virtio_vdpa support for mlx5

 - Validate device input in several drivers (for SEV and friends)

 - ZONE_MOVABLE aware handling in virtio-mem

 - Misc fixes, cleanups

* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: (48 commits)
  virtio-mem: prioritize unplug from ZONE_MOVABLE in Big Block Mode
  virtio-mem: simplify high-level unplug handling in Big Block Mode
  virtio-mem: prioritize unplug from ZONE_MOVABLE in Sub Block Mode
  virtio-mem: simplify high-level unplug handling in Sub Block Mode
  virtio-mem: simplify high-level plug handling in Sub Block Mode
  virtio-mem: use page_zonenum() in virtio_mem_fake_offline()
  virtio-mem: don't read big block size in Sub Block Mode
  virtio/vdpa: clear the virtqueue state during probe
  vp_vdpa: allow set vq state to initial state after reset
  virtio-pci library: introduce vp_modern_get_driver_features()
  vdpa: support packed virtqueue for set/get_vq_state()
  virtio-ring: store DMA metadata in desc_extra for split virtqueue
  virtio: use err label in __vring_new_virtqueue()
  virtio_ring: introduce virtqueue_desc_add_split()
  virtio_ring: secure handling of mapping errors
  virtio-ring: factor out desc_extra allocation
  virtio_ring: rename vring_desc_extra_packed
  virtio-ring: maintain next in extra state for packed virtqueue
  vdpa/mlx5: Clear vq ready indication upon device reset
  vdpa/mlx5: Add support for doorbell bypassing
  ...
parents d8dc121e db7b3377
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -21,6 +21,9 @@
#define VQ_NAME_LEN 16
#define MAX_DISCARD_SEGMENTS 256u

/* The maximum number of sg elements that fit into a virtqueue */
#define VIRTIO_BLK_MAX_SG_ELEMS 32768

static int major;
static DEFINE_IDA(vd_index_ida);

@@ -447,13 +450,6 @@ static void virtblk_update_capacity(struct virtio_blk *vblk, bool resize)
	/* Host must always specify the capacity. */
	virtio_cread(vdev, struct virtio_blk_config, capacity, &capacity);

	/* If capacity is too big, truncate with warning. */
	if ((sector_t)capacity != capacity) {
		dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n",
			 (unsigned long long)capacity);
		capacity = (sector_t)-1;
	}

	nblocks = DIV_ROUND_UP_ULL(capacity, queue_logical_block_size(q) >> 9);

	string_get_size(nblocks, queue_logical_block_size(q),
@@ -728,7 +724,10 @@ static int virtblk_probe(struct virtio_device *vdev)
	if (err || !sg_elems)
		sg_elems = 1;

	/* We need an extra sg elements at head and tail. */
	/* Prevent integer overflows and honor max vq size */
	sg_elems = min_t(u32, sg_elems, VIRTIO_BLK_MAX_SG_ELEMS - 2);

	/* We need extra sg elements at head and tail. */
	sg_elems += 2;
	vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL);
	if (!vblk) {
@@ -936,6 +935,8 @@ static int virtblk_freeze(struct virtio_device *vdev)
	blk_mq_quiesce_queue(vblk->disk->queue);

	vdev->config->del_vqs(vdev);
	kfree(vblk->vqs);

	return 0;
}

+2 −2
Original line number Diff line number Diff line
@@ -475,7 +475,7 @@ static struct port_buffer *get_inbuf(struct port *port)

	buf = virtqueue_get_buf(port->in_vq, &len);
	if (buf) {
		buf->len = len;
		buf->len = min_t(size_t, len, buf->size);
		buf->offset = 0;
		port->stats.bytes_received += len;
	}
@@ -1709,7 +1709,7 @@ static void control_work_handler(struct work_struct *work)
	while ((buf = virtqueue_get_buf(vq, &len))) {
		spin_unlock(&portdev->c_ivq_lock);

		buf->len = len;
		buf->len = min_t(size_t, len, buf->size);
		buf->offset = 0;

		handle_control_message(vq->vdev, portdev, buf);
+42 −11
Original line number Diff line number Diff line
@@ -1516,12 +1516,16 @@ static void virtnet_poll_cleantx(struct receive_queue *rq)
		return;

	if (__netif_tx_trylock(txq)) {
		do {
			virtqueue_disable_cb(sq->vq);
			free_old_xmit_skbs(sq, true);
		__netif_tx_unlock(txq);
	}
		} while (unlikely(!virtqueue_enable_cb_delayed(sq->vq)));

		if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS)
			netif_tx_wake_queue(txq);

		__netif_tx_unlock(txq);
	}
}

static int virtnet_poll(struct napi_struct *napi, int budget)
@@ -1592,6 +1596,8 @@ static int virtnet_poll_tx(struct napi_struct *napi, int budget)
	struct virtnet_info *vi = sq->vq->vdev->priv;
	unsigned int index = vq2txq(sq->vq);
	struct netdev_queue *txq;
	int opaque;
	bool done;

	if (unlikely(is_xdp_raw_buffer_queue(vi, index))) {
		/* We don't need to enable cb for XDP */
@@ -1601,14 +1607,32 @@ static int virtnet_poll_tx(struct napi_struct *napi, int budget)

	txq = netdev_get_tx_queue(vi->dev, index);
	__netif_tx_lock(txq, raw_smp_processor_id());
	virtqueue_disable_cb(sq->vq);
	free_old_xmit_skbs(sq, true);
	__netif_tx_unlock(txq);

	virtqueue_napi_complete(napi, sq->vq, 0);

	if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS)
		netif_tx_wake_queue(txq);

	opaque = virtqueue_enable_cb_prepare(sq->vq);

	done = napi_complete_done(napi, 0);

	if (!done)
		virtqueue_disable_cb(sq->vq);

	__netif_tx_unlock(txq);

	if (done) {
		if (unlikely(virtqueue_poll(sq->vq, opaque))) {
			if (napi_schedule_prep(napi)) {
				__netif_tx_lock(txq, raw_smp_processor_id());
				virtqueue_disable_cb(sq->vq);
				__netif_tx_unlock(txq);
				__napi_schedule(napi);
			}
		}
	}

	return 0;
}

@@ -1670,10 +1694,14 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
	bool use_napi = sq->napi.weight;

	/* Free up any pending old buffers before queueing new ones. */
	do {
		if (use_napi)
			virtqueue_disable_cb(sq->vq);

		free_old_xmit_skbs(sq, false);

	if (use_napi && kick)
		virtqueue_enable_cb_delayed(sq->vq);
	} while (use_napi && kick &&
	       unlikely(!virtqueue_enable_cb_delayed(sq->vq)));

	/* timestamp packet in software */
	skb_tx_timestamp(skb);
@@ -3310,8 +3338,11 @@ static __maybe_unused int virtnet_restore(struct virtio_device *vdev)
	virtnet_set_queues(vi, vi->curr_queue_pairs);

	err = virtnet_cpu_notif_add(vi);
	if (err)
	if (err) {
		virtnet_freeze_down(vdev);
		remove_vq_common(vi);
		return err;
	}

	return 0;
}
+4 −0
Original line number Diff line number Diff line
@@ -133,6 +133,8 @@ int ifcvf_init_hw(struct ifcvf_hw *hw, struct pci_dev *pdev)
					      &hw->notify_off_multiplier);
			hw->notify_bar = cap.bar;
			hw->notify_base = get_cap_addr(hw, &cap);
			hw->notify_base_pa = pci_resource_start(pdev, cap.bar) +
					le32_to_cpu(cap.offset);
			IFCVF_DBG(pdev, "hw->notify_base = %p\n",
				  hw->notify_base);
			break;
@@ -161,6 +163,8 @@ int ifcvf_init_hw(struct ifcvf_hw *hw, struct pci_dev *pdev)
		notify_off = ifc_ioread16(&hw->common_cfg->queue_notify_off);
		hw->vring[i].notify_addr = hw->notify_base +
			notify_off * hw->notify_off_multiplier;
		hw->vring[i].notify_pa = hw->notify_base_pa +
			notify_off * hw->notify_off_multiplier;
	}

	hw->lm_cfg = hw->base[IFCVF_LM_BAR];
+2 −12
Original line number Diff line number Diff line
@@ -19,21 +19,9 @@
#include <uapi/linux/virtio_config.h>
#include <uapi/linux/virtio_pci.h>

#define N3000_VENDOR_ID		0x1AF4
#define N3000_DEVICE_ID		0x1041
#define N3000_SUBSYS_VENDOR_ID	0x8086
#define N3000_SUBSYS_DEVICE_ID	0x001A

#define C5000X_PL_VENDOR_ID		0x1AF4
#define C5000X_PL_DEVICE_ID		0x1000
#define C5000X_PL_SUBSYS_VENDOR_ID	0x8086
#define C5000X_PL_SUBSYS_DEVICE_ID	0x0001

#define C5000X_PL_BLK_VENDOR_ID		0x1AF4
#define C5000X_PL_BLK_DEVICE_ID		0x1001
#define C5000X_PL_BLK_SUBSYS_VENDOR_ID	0x8086
#define C5000X_PL_BLK_SUBSYS_DEVICE_ID	0x0002

#define IFCVF_NET_SUPPORTED_FEATURES \
		((1ULL << VIRTIO_NET_F_MAC)			| \
		 (1ULL << VIRTIO_F_ANY_LAYOUT)			| \
@@ -73,6 +61,7 @@ struct vring_info {
	u16 last_avail_idx;
	bool ready;
	void __iomem *notify_addr;
	phys_addr_t notify_pa;
	u32 irq;
	struct vdpa_callback cb;
	char msix_name[256];
@@ -87,6 +76,7 @@ struct ifcvf_hw {
	u8 notify_bar;
	/* Notificaiton bar address */
	void __iomem *notify_base;
	phys_addr_t notify_base_pa;
	u32 notify_off_multiplier;
	u64 req_features;
	u64 hw_features;
Loading