[RFCv2 03/12] virtio-ring: Introduce file virtio_ring_host

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Move host-side virtio ring functions to file virtio_ring_host.c
The functions vring_avail_desc_user(), vring_add_used_user() and
vring_next_desc() are moved from vhost.c to the new file
virtio_ring_host.c. (The functions are copied as is without any changes)

Signed-off-by: Sjur Brændeland <sjur.brandeland@xxxxxxxxxxxxxx>
---
 drivers/vhost/Kconfig             |    2 +
 drivers/vhost/vhost.c             |   92 -----------------------------
 drivers/virtio/Kconfig            |    3 +
 drivers/virtio/Makefile           |    1 +
 drivers/virtio/virtio_ring_host.c |  117 +++++++++++++++++++++++++++++++++++++
 include/linux/virtio_ring.h       |    8 +++
 6 files changed, 131 insertions(+), 92 deletions(-)
 create mode 100644 drivers/virtio/virtio_ring_host.c

diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig
index 202bba6..5bfdaa9 100644
--- a/drivers/vhost/Kconfig
+++ b/drivers/vhost/Kconfig
@@ -1,4 +1,6 @@
 config VHOST_NET
+	select VIRTIO_RING_HOST
+	select VIRTIO
 	tristate "Host kernel accelerator for virtio net (EXPERIMENTAL)"
 	depends on NET && EVENTFD && (TUN || !TUN) && (MACVTAP || !MACVTAP) && EXPERIMENTAL
 	---help---
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 5e91048..6634f0a 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -1097,27 +1097,6 @@ static int translate_desc(struct vhost_dev *dev, u64 addr, u32 len,
 	return ret;
 }
 
-/* Each buffer in the virtqueues is actually a chain of descriptors.  This
- * function returns the next descriptor in the chain,
- * or -1U if we're at the end. */
-unsigned vring_next_desc(struct vring_desc *desc)
-{
-	unsigned int next;
-
-	/* If this descriptor says it doesn't chain, we're done. */
-	if (!(desc->flags & VRING_DESC_F_NEXT))
-		return -1U;
-
-	/* Check they're not leading us off end of descriptors. */
-	next = desc->next;
-	/* Make sure compiler knows to grab that: we don't want it changing! */
-	/* We will use the result as an index in an array, so most
-	 * architectures only need a compiler barrier here. */
-	read_barrier_depends();
-
-	return next;
-}
-
 static int get_indirect(struct vhost_dev *dev, struct vhost_virtqueue *vq,
 			struct iovec iov[], unsigned int iov_size,
 			unsigned int *out_num, unsigned int *in_num,
@@ -1206,51 +1185,6 @@ static int get_indirect(struct vhost_dev *dev, struct vhost_virtqueue *vq,
 	return 0;
 }
 
-static int vring_avail_desc_user(struct vring_host *vh)
-{
-	int head;
-	u16 last_avail_idx;
-
-	/* Check it isn't doing very strange things with descriptor numbers. */
-	last_avail_idx = vh->last_avail_idx;
-	if (unlikely(__get_user(vh->avail_idx, &vh->vr.avail->idx))) {
-		pr_debug("Failed to access avail idx at %p\n",
-		       &vh->vr.avail->idx);
-		return -EFAULT;
-	}
-
-	if (unlikely((u16)(vh->avail_idx - last_avail_idx) > vh->vr.num))
-		return -EFAULT;
-
-	/* If there's nothing new since last we looked, return invalid. */
-	if (vh->avail_idx == last_avail_idx)
-		return vh->vr.num;
-
-	/* Only get avail ring entries after they have been exposed by guest. */
-	smp_rmb();
-
-	/* Grab the next descriptor number they're advertising, and increment
-	 * the index we've seen. */
-	if (unlikely(__get_user(head,
-				&vh->vr.avail->ring[last_avail_idx %
-							vh->vr.num]))) {
-		pr_debug("Failed to read head: idx %d address %p\n",
-			 last_avail_idx,
-		       &vh->vr.avail->ring[last_avail_idx %
-					       vh->vr.num]);
-		return -EFAULT;
-	}
-
-	/* If their number is silly, that's an error. */
-	if (unlikely(head >= vh->vr.num)) {
-		pr_debug("Guest says index %u > %u is available",
-		       head, vh->vr.num);
-		return -EINVAL;
-	}
-
-	return head;
-}
-
 /* This looks in the virtqueue and for the first available buffer, and converts
  * it to an iovec for convenient access.  Since descriptors consist of some
  * number of output then some number of input descriptors, it's actually two
@@ -1352,32 +1286,6 @@ void vhost_discard_vq_desc(struct vhost_virtqueue *vq, int n)
 	vq->hst.last_avail_idx -= n;
 }
 
-struct vring_used_elem *vring_add_used_user(struct vring_host *vh,
-				     unsigned int head, int len)
-{
-	struct vring_used_elem  *used;
-
-	/* The virtqueue contains a ring of used buffers.  Get a pointer to the
-	 * next entry in that used ring. */
-	used = &vh->vr.used->ring[vh->last_used_idx % vh->vr.num];
-	if (__put_user(head, &used->id)) {
-		pr_debug("Failed to write used id");
-		return NULL;
-	}
-	if (__put_user(len, &used->len)) {
-		pr_debug("Failed to write used len");
-		return NULL;
-	}
-	/* Make sure buffer is written before we update index. */
-	smp_wmb();
-	if (__put_user(vh->last_used_idx + 1, &vh->vr.used->idx)) {
-		pr_debug("Failed to increment used idx");
-		return NULL;
-	}
-	vh->last_used_idx++;
-	return used;
-}
-
 /* After we've used one of their buffers, we tell them about it.  We'll then
  * want to notify the guest, using eventfd. */
 int vhost_add_used(struct vhost_virtqueue *vq, unsigned int head, int len)
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 8d5bddb..4e72892 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -5,6 +5,9 @@ config VIRTIO
 	  bus, such as CONFIG_VIRTIO_PCI, CONFIG_VIRTIO_MMIO, CONFIG_LGUEST,
 	  CONFIG_RPMSG or CONFIG_S390_GUEST.
 
+config VIRTIO_RING_HOST
+	tristate
+
 menu "Virtio drivers"
 
 config VIRTIO_PCI
diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
index 9076635..54831f4 100644
--- a/drivers/virtio/Makefile
+++ b/drivers/virtio/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_VIRTIO) += virtio.o virtio_ring.o
+obj-$(CONFIG_VIRTIO_RING_HOST) += virtio_ring_host.o
 obj-$(CONFIG_VIRTIO_MMIO) += virtio_mmio.o
 obj-$(CONFIG_VIRTIO_PCI) += virtio_pci.o
 obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
diff --git a/drivers/virtio/virtio_ring_host.c b/drivers/virtio/virtio_ring_host.c
new file mode 100644
index 0000000..192b838
--- /dev/null
+++ b/drivers/virtio/virtio_ring_host.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2012
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2006 Rusty Russell IBM Corporation
+ * Copyring
+ *
+ * Author:  Sjur Brendeland / sjur.brandeland@xxxxxxxxxxxxxx
+ * Copied from vhost.c, author Michael S. Tsirkin <mst@xxxxxxxxxx>
+ *
+ * License terms: GNU General Public License (GPL) version 2.
+ *
+ * Inspiration, some code, and most witty comments come from
+ * Documentation/virtual/lguest/lguest.c, by Rusty Russell
+ *
+ * Generic code for virtio server in host kernel.
+ */
+#include <linux/virtio.h>
+#include <linux/virtio_ring.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+
+MODULE_LICENSE("GPL");
+
+struct vring_used_elem *vring_add_used_user(struct vring_host *vh,
+				     unsigned int head, int len)
+{
+	struct vring_used_elem  *used;
+
+	/* The virtqueue contains a ring of used buffers.  Get a pointer to the
+	 * next entry in that used ring. */
+	used = &vh->vr.used->ring[vh->last_used_idx % vh->vr.num];
+	if (__put_user(head, &used->id)) {
+		pr_debug("Failed to write used id");
+		return NULL;
+	}
+	if (__put_user(len, &used->len)) {
+		pr_debug("Failed to write used len");
+		return NULL;
+	}
+	/* Make sure buffer is written before we update index. */
+	smp_wmb();
+	if (__put_user(vh->last_used_idx + 1, &vh->vr.used->idx)) {
+		pr_debug("Failed to increment used idx");
+		return NULL;
+	}
+	vh->last_used_idx++;
+	return used;
+}
+EXPORT_SYMBOL(vring_add_used_user);
+
+int vring_avail_desc_user(struct vring_host *vh)
+{
+	int head;
+	u16 last_avail_idx;
+
+	/* Check it isn't doing very strange things with descriptor numbers. */
+	last_avail_idx = vh->last_avail_idx;
+	if (unlikely(__get_user(vh->avail_idx, &vh->vr.avail->idx))) {
+		pr_debug("Failed to access avail idx at %p\n",
+		       &vh->vr.avail->idx);
+		return -EFAULT;
+	}
+
+	if (unlikely((u16)(vh->avail_idx - last_avail_idx) > vh->vr.num))
+		return -EFAULT;
+
+	/* If there's nothing new since last we looked, return invalid. */
+	if (vh->avail_idx == last_avail_idx)
+		return vh->vr.num;
+
+	/* Only get avail ring entries after they have been exposed by guest. */
+	smp_rmb();
+
+	/* Grab the next descriptor number they're advertising, and increment
+	 * the index we've seen. */
+	if (unlikely(__get_user(head,
+				&vh->vr.avail->ring[last_avail_idx %
+							vh->vr.num]))) {
+		pr_debug("Failed to read head: idx %d address %p\n",
+			 last_avail_idx,
+		       &vh->vr.avail->ring[last_avail_idx %
+					       vh->vr.num]);
+		return -EFAULT;
+	}
+
+	/* If their number is silly, that's an error. */
+	if (unlikely(head >= vh->vr.num)) {
+		pr_debug("Guest says index %u > %u is available",
+		       head, vh->vr.num);
+		return -EINVAL;
+	}
+
+	return head;
+}
+EXPORT_SYMBOL(vring_avail_desc_user);
+
+/* Each buffer in the virtqueues is actually a chain of descriptors.  This
+ * function returns the next descriptor in the chain,
+ * or -1U if we're at the end. */
+unsigned vring_next_desc(struct vring_desc *desc)
+{
+	unsigned int next;
+
+	/* If this descriptor says it doesn't chain, we're done. */
+	if (!(desc->flags & VRING_DESC_F_NEXT))
+		return -1U;
+
+	/* Check they're not leading us off end of descriptors. */
+	next = desc->next;
+	/* Make sure compiler knows to grab that: we don't want it changing! */
+	/* We will use the result as an index in an array, so most
+	 * architectures only need a compiler barrier here. */
+	read_barrier_depends();
+
+	return next;
+}
+EXPORT_SYMBOL(vring_next_desc);
diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h
index 7917dac..6c9b871 100644
--- a/include/linux/virtio_ring.h
+++ b/include/linux/virtio_ring.h
@@ -34,4 +34,12 @@ void vring_del_virtqueue(struct virtqueue *vq);
 void vring_transport_features(struct virtio_device *vdev);
 
 irqreturn_t vring_interrupt(int irq, void *_vq);
+
+unsigned vring_next_desc(struct vring_desc *desc);
+
+int vring_avail_desc_user(struct vring_host *vh);
+
+struct vring_used_elem *vring_add_used_user(struct vring_host *vh,
+					    unsigned int head, int len);
+
 #endif /* _LINUX_VIRTIO_RING_H */
-- 
1.7.5.4

_______________________________________________
Virtualization mailing list
Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linuxfoundation.org/mailman/listinfo/virtualization



[Index of Archives]     [KVM Development]     [Libvirt Development]     [Libvirt Users]     [CentOS Virtualization]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux