All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gregory Haskins <ghaskins@novell.com>
To: kvm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, ghaskins@novell.com
Subject: [PATCH v2 4/4] KVM: add scatterlist support to xinterface
Date: Fri, 02 Oct 2009 16:19:38 -0400	[thread overview]
Message-ID: <20091002201937.4014.96148.stgit@dev.haskins.net> (raw)
In-Reply-To: <20091002201159.4014.33268.stgit@dev.haskins.net>

This allows a scatter-gather approach to IO, which will be useful for
building high performance interfaces, like zero-copy and low-latency
copy (avoiding multiple calls to copy_to/from).

The interface is based on the existing scatterlist infrastructure.  The
caller is expected to pass in a scatterlist with its "dma" field
populated with valid GPAs.  The xinterface will then populate each
entry by translating the GPA to a page*.

The caller signifies completion by simply performing a put_page() on
each page returned in the list.

Signed-off-by: Gregory Haskins <ghaskins@novell.com>
---

 include/linux/kvm_xinterface.h |    4 ++
 virt/kvm/xinterface.c          |   72 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/include/linux/kvm_xinterface.h b/include/linux/kvm_xinterface.h
index 684b6f8..eefb575 100644
--- a/include/linux/kvm_xinterface.h
+++ b/include/linux/kvm_xinterface.h
@@ -9,6 +9,7 @@
 #include <linux/kref.h>
 #include <linux/module.h>
 #include <linux/file.h>
+#include <linux/scatterlist.h>
 
 struct kvm_xinterface;
 struct kvm_xvmap;
@@ -36,6 +37,9 @@ struct kvm_xinterface_ops {
 					u64 addr,
 					unsigned long len,
 					unsigned long flags);
+	unsigned long (*sgmap)(struct kvm_xinterface *intf,
+			       struct scatterlist *sgl, int nents,
+			       unsigned long flags);
 	void (*release)(struct kvm_xinterface *);
 };
 
diff --git a/virt/kvm/xinterface.c b/virt/kvm/xinterface.c
index c356835..16729f6 100644
--- a/virt/kvm/xinterface.c
+++ b/virt/kvm/xinterface.c
@@ -467,6 +467,77 @@ fail:
 
 }
 
+static unsigned long
+xinterface_sgmap(struct kvm_xinterface *intf,
+		 struct scatterlist *sgl, int nents,
+		 unsigned long flags)
+{
+	struct _xinterface     *_intf   = to_intf(intf);
+	struct task_struct     *p       = _intf->task;
+	struct mm_struct       *mm      = _intf->mm;
+	struct kvm             *kvm     = _intf->kvm;
+	struct kvm_memory_slot *memslot = NULL;
+	bool                    kthread = !current->mm;
+	int                     ret;
+	struct scatterlist     *sg;
+	int                     i;
+
+	down_read(&kvm->slots_lock);
+
+	if (kthread)
+		use_mm(_intf->mm);
+
+	for_each_sg(sgl, sg, nents, i) {
+		unsigned long           gpa    = sg_dma_address(sg);
+		unsigned long           len    = sg_dma_len(sg);
+		unsigned long           gfn    = gpa >> PAGE_SHIFT;
+		off_t                   offset = offset_in_page(gpa);
+		unsigned long           hva;
+		struct page            *pg;
+
+		/* ensure that we do not have more than one page per entry */
+		if ((PAGE_ALIGN(len + offset) >> PAGE_SHIFT) != 1) {
+			ret = -EINVAL;
+			break;
+		}
+
+		/* check for a memslot-cache miss */
+		if (!memslot
+		    || gfn < memslot->base_gfn
+		    || gfn >= memslot->base_gfn + memslot->npages) {
+			memslot = gfn_to_memslot(kvm, gfn);
+			if (!memslot) {
+				ret = -EFAULT;
+				break;
+			}
+		}
+
+		hva = (memslot->userspace_addr +
+		       (gfn - memslot->base_gfn) * PAGE_SIZE);
+
+		if (kthread || current->mm == mm)
+			ret = get_user_pages_fast(hva, 1, 1, &pg);
+		else
+			ret = get_user_pages(p, mm, hva, 1, 1, 0, &pg, NULL);
+
+		if (ret != 1) {
+			if (ret >= 0)
+				ret = -EFAULT;
+			break;
+		}
+
+		sg_set_page(sg, pg, len, offset);
+		ret = 0;
+	}
+
+	if (kthread)
+		unuse_mm(_intf->mm);
+
+	up_read(&kvm->slots_lock);
+
+	return ret;
+}
+
 static void
 xinterface_release(struct kvm_xinterface *intf)
 {
@@ -483,6 +554,7 @@ struct kvm_xinterface_ops _xinterface_ops = {
 	.copy_from   = xinterface_copy_from,
 	.vmap        = xinterface_vmap,
 	.ioevent     = xinterface_ioevent,
+	.sgmap       = xinterface_sgmap,
 	.release     = xinterface_release,
 };
 


  parent reply	other threads:[~2009-10-02 20:19 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-02 20:19 [PATCH v2 0/4] KVM: xinterface Gregory Haskins
2009-10-02 20:19 ` [PATCH v2 1/4] mm: export use_mm() and unuse_mm() to modules Gregory Haskins
2009-10-02 20:19 ` [PATCH v2 2/4] KVM: introduce "xinterface" API for external interaction with guests Gregory Haskins
2009-10-03 20:05   ` Marcelo Tosatti
2009-10-05 23:33     ` Gregory Haskins
2009-10-04 10:25   ` Avi Kivity
2009-10-05 23:57     ` Gregory Haskins
2009-10-06  9:34       ` Avi Kivity
2009-10-06 13:31         ` Gregory Haskins
2009-10-06 14:22           ` Gregory Haskins
2009-10-06 16:23             ` Avi Kivity
2009-10-06 17:00               ` Gregory Haskins
2009-10-06 17:00                 ` Gregory Haskins
2009-10-06 19:40                   ` Gregory Haskins
2009-10-07  8:11                     ` Avi Kivity
2009-10-07 12:48                       ` Gregory Haskins
2009-10-08 14:45                         ` Avi Kivity
2009-10-06 16:19           ` Avi Kivity
2009-10-06 16:58             ` Gregory Haskins
2009-10-06 18:18               ` [Alacrityvm-devel] " Ira W. Snyder
2009-10-07  5:10                 ` Amit Shah
2009-10-07  7:43                 ` Avi Kivity
2009-10-02 20:19 ` [PATCH v2 3/4] KVM: add io services to xinterface Gregory Haskins
2009-10-04 10:26   ` Avi Kivity
2009-10-02 20:19 ` Gregory Haskins [this message]
2009-10-04 10:28   ` [PATCH v2 4/4] KVM: add scatterlist support " Avi Kivity
2009-10-05 23:57     ` Gregory Haskins

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20091002201937.4014.96148.stgit@dev.haskins.net \
    --to=ghaskins@novell.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.