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

[Xen-devel] [PATCH RFC 32/39] xen/balloon: xen_shim_domain() support



Xen ballooning uses hollow struct pages (with the underlying PFNs being
populated/unpopulated via hypercalls) which are used by the grant logic
to map grants from other domains.

For purposes of a KVM based xen-shim, this model is not useful --
mapping is unnecessary since all guest memory is already mapped in the
KVM host. The simplest option is to just translate grant references to
GPAs (essentially a get_page() on the appropriate GPA.)

This patch provides an alternate balloon allocation mechanism where in
the allocation path we just provide a constant struct page
(corresponding to page 0.) This allows the calling code -- which does a
page_to_pfn() on the returned struct page -- to remain unchanged before
doing the grant operation (which in this case would fill in the real
struct page.)

Co-developed-by: Ankur Arora <ankur.a.arora@xxxxxxxxxx>
Signed-off-by: Joao Martins <joao.m.martins@xxxxxxxxxx>
Signed-off-by: Ankur Arora <ankur.a.arora@xxxxxxxxxx>
---
 arch/x86/kvm/xen-shim.c | 31 +++++++++++++++++++++++++++++++
 drivers/xen/balloon.c   | 15 ++++++++++++++-
 include/xen/balloon.h   |  7 +++++++
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/xen-shim.c b/arch/x86/kvm/xen-shim.c
index 61fdceb63ec2..4086d92a4bfb 100644
--- a/arch/x86/kvm/xen-shim.c
+++ b/arch/x86/kvm/xen-shim.c
@@ -13,11 +13,40 @@
 #include <xen/xen-ops.h>
 #include <xen/events.h>
 #include <xen/xenbus.h>
+#include <xen/balloon.h>
 
 #define BITS_PER_EVTCHN_WORD (sizeof(xen_ulong_t)*8)
 
 static struct kvm_xen shim = { .domid = XEN_SHIM_DOMID };
 
+static int shim_alloc_pages(int nr_pages, struct page **pages)
+{
+       int i;
+
+       /*
+        * We provide page 0 instead of NULL because we'll effectively
+        * do the inverse operation while deriving the pfn to pass to
+        * xen for mapping.
+        */
+       for (i = 0; i < nr_pages; i++)
+               pages[i] = pfn_to_page(0);
+
+       return 0;
+}
+
+static void shim_free_pages(int nr_pages, struct page **pages)
+{
+       int i;
+
+       for (i = 0; i < nr_pages; i++)
+               pages[i] = NULL;
+}
+
+static struct xen_balloon_ops shim_balloon_ops = {
+       .alloc_pages = shim_alloc_pages,
+       .free_pages = shim_free_pages,
+};
+
 static void shim_evtchn_setup(struct shared_info *s)
 {
        int cpu;
@@ -65,6 +94,7 @@ static int __init shim_register(void)
        mutex_init(&shim.xen_lock);
 
        kvm_xen_register_lcall(&shim);
+       xen_balloon_ops = &shim_balloon_ops;
 
        /* We can handle hypercalls after this point */
        xen_shim_domain = 1;
@@ -94,6 +124,7 @@ static void __exit shim_exit(void)
        xen_shim_domain = 0;
 
        kvm_xen_unregister_lcall();
+       xen_balloon_ops = NULL;
        HYPERVISOR_shared_info = NULL;
        free_page((unsigned long) shim.shinfo);
        shim.shinfo = NULL;
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index ceb5048de9a7..00375fa6c122 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -138,7 +138,7 @@ enum bp_state {
 
 static DEFINE_MUTEX(balloon_mutex);
 
-struct balloon_stats balloon_stats;
+struct balloon_stats balloon_stats __read_mostly;
 EXPORT_SYMBOL_GPL(balloon_stats);
 
 /* We increase/decrease in batches which fit in a page */
@@ -158,6 +158,9 @@ static DECLARE_DELAYED_WORK(balloon_worker, 
balloon_process);
 #define GFP_BALLOON \
        (GFP_HIGHUSER | __GFP_NOWARN | __GFP_NORETRY | __GFP_NOMEMALLOC)
 
+struct xen_balloon_ops *xen_balloon_ops;
+EXPORT_SYMBOL(xen_balloon_ops);
+
 /* balloon_append: add the given page to the balloon. */
 static void __balloon_append(struct page *page)
 {
@@ -589,6 +592,11 @@ int alloc_xenballooned_pages(int nr_pages, struct page 
**pages)
        struct page *page;
        int ret;
 
+       if (xen_shim_domain() && xen_balloon_ops)
+               return xen_balloon_ops->alloc_pages(nr_pages, pages);
+
+       WARN_ON_ONCE(xen_shim_domain());
+
        mutex_lock(&balloon_mutex);
 
        balloon_stats.target_unpopulated += nr_pages;
@@ -634,6 +642,11 @@ void free_xenballooned_pages(int nr_pages, struct page 
**pages)
 {
        int i;
 
+       if (xen_shim_domain() && xen_balloon_ops)
+               return xen_balloon_ops->free_pages(nr_pages, pages);
+
+       WARN_ON_ONCE(xen_shim_domain());
+
        mutex_lock(&balloon_mutex);
 
        for (i = 0; i < nr_pages; i++) {
diff --git a/include/xen/balloon.h b/include/xen/balloon.h
index 4914b93a23f2..9ba6a7e91d5e 100644
--- a/include/xen/balloon.h
+++ b/include/xen/balloon.h
@@ -22,6 +22,13 @@ struct balloon_stats {
 
 extern struct balloon_stats balloon_stats;
 
+struct xen_balloon_ops {
+       int (*alloc_pages)(int nr_pages, struct page **pages);
+       void (*free_pages)(int nr_pages, struct page **pages);
+};
+
+extern struct xen_balloon_ops *xen_balloon_ops;
+
 void balloon_set_new_target(unsigned long target);
 
 int alloc_xenballooned_pages(int nr_pages, struct page **pages);
-- 
2.11.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.