WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 2/3] xen-fbfront: Use grant references when requested

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 2/3] xen-fbfront: Use grant references when requested
From: dgdegra@xxxxxxxxxxxxx
Date: Fri, 7 Jan 2011 11:12:58 -0500
Cc: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
Delivery-date: Fri, 07 Jan 2011 08:18:29 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <1294416779-13833-1-git-send-email-dgdegra@xxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <1294416779-13833-1-git-send-email-dgdegra@xxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
From: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>

The current version of the Xen framebuffer API passes MFNs directly
to the backend driver, which requires the backend to have full access
to this domain's memory. Add a parameter in xenbus to request the use of
grant entries instead, which are slightly slower to map but provide
inter-domain isolation.

Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
---
 drivers/video/xen-fbfront.c |   73 +++++++++++++++++++++++++++++++++---------
 1 files changed, 57 insertions(+), 16 deletions(-)

diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
index 341c919..bb99bbd 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/xen-fbfront.c
@@ -11,13 +11,6 @@
  *  more details.
  */
 
-/*
- * TODO:
- *
- * Switch to grant tables when they become capable of dealing with the
- * frame buffer.
- */
-
 #include <linux/console.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -32,6 +25,8 @@
 #include <xen/xen.h>
 #include <xen/events.h>
 #include <xen/page.h>
+#include <xen/grant_table.h>
+#include <xen/interface/grant_table.h>
 #include <xen/interface/io/fbif.h>
 #include <xen/interface/io/protocols.h>
 #include <xen/xenbus.h>
@@ -46,6 +41,7 @@ struct xenfb_info {
        int                     irq;
        struct xenfb_page       *page;
        unsigned long           *mfns;
+       int                     page_gref;
        int                     update_wanted; /* XENFB_TYPE_UPDATE wanted */
        int                     feature_resize; /* XENFB_TYPE_RESIZE ok */
        struct xenfb_resize     resize;         /* protected by resize_lock */
@@ -65,7 +61,7 @@ MODULE_PARM_DESC(video,
 
 static void xenfb_make_preferred_console(void);
 static int xenfb_remove(struct xenbus_device *);
-static void xenfb_init_shared_page(struct xenfb_info *, struct fb_info *);
+static void xenfb_init_shared_page(struct xenbus_device *, struct xenfb_info 
*, struct fb_info *);
 static int xenfb_connect_backend(struct xenbus_device *, struct xenfb_info *);
 static void xenfb_disconnect_backend(struct xenfb_info *);
 
@@ -474,7 +470,7 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
        fb_info->fbdefio = &xenfb_defio;
        fb_deferred_io_init(fb_info);
 
-       xenfb_init_shared_page(info, fb_info);
+       xenfb_init_shared_page(dev, info, fb_info);
 
        ret = xenfb_connect_backend(dev, info);
        if (ret < 0)
@@ -528,7 +524,7 @@ static int xenfb_resume(struct xenbus_device *dev)
        struct xenfb_info *info = dev_get_drvdata(&dev->dev);
 
        xenfb_disconnect_backend(info);
-       xenfb_init_shared_page(info, info->fb_info);
+       xenfb_init_shared_page(dev, info, info->fb_info);
        return xenfb_connect_backend(dev, info);
 }
 
@@ -556,17 +552,58 @@ static unsigned long vmalloc_to_mfn(void *address)
        return pfn_to_mfn(vmalloc_to_pfn(address));
 }
 
-static void xenfb_init_shared_page(struct xenfb_info *info,
+static void xenfb_init_shared_page(struct xenbus_device *dev,
+                                   struct xenfb_info *info,
                                   struct fb_info *fb_info)
 {
-       int i;
        int epd = PAGE_SIZE / sizeof(info->mfns[0]);
+       int be_id = dev->otherend_id;
+       int i, ref;
+       unsigned long mfn;
+       grant_ref_t gref_head;
+       int allpages = info->nr_pages + ((info->nr_pages + epd - 1) / epd) + 1;
+
+       int grants = 0;
+       xenbus_scanf(XBT_NIL, dev->otherend, "use-grants", "%d", &grants);
+
+       if (grants) {
+               int err = gnttab_alloc_grant_references(allpages, &gref_head);
+               if (err < 0) {
+                       xenbus_dev_fatal(dev, err, "fbdev grant refs");
+                       info->page_gref = -ENOSPC;
+               } else {
+                       ref = gnttab_claim_grant_reference(&gref_head);
+                       mfn = virt_to_mfn(info->page);
+                       BUG_ON(ref == -ENOSPC);
+                       gnttab_grant_foreign_access_ref(ref, be_id, mfn, 0);
+                       info->page_gref = ref;
+               }
+       } else
+               info->page_gref = -ENOENT;
 
        for (i = 0; i < info->nr_pages; i++)
-               info->mfns[i] = vmalloc_to_mfn(info->fb + i * PAGE_SIZE);
+       {
+               mfn = vmalloc_to_mfn(info->fb + i * PAGE_SIZE);
+               if (grants) {
+                       ref = gnttab_claim_grant_reference(&gref_head);
+                       BUG_ON(ref == -ENOSPC);
+                       gnttab_grant_foreign_access_ref(ref, be_id, mfn, 1);
+                       info->mfns[i] = ref;
+               } else
+                       info->mfns[i] = mfn;
+       }
 
        for (i = 0; i * epd < info->nr_pages; i++)
-               info->page->pd[i] = vmalloc_to_mfn(&info->mfns[i * epd]);
+       {
+               mfn = vmalloc_to_mfn(&info->mfns[i * epd]);
+               if (grants) {
+                       ref = gnttab_claim_grant_reference(&gref_head);
+                       BUG_ON(ref == -ENOSPC);
+                       gnttab_grant_foreign_access_ref(ref, be_id, mfn, 1);
+                       info->page->pd[i] = ref;
+               } else
+                       info->page->pd[i] = mfn;
+       }
 
        info->page->width = fb_info->var.xres;
        info->page->height = fb_info->var.yres;
@@ -601,8 +638,12 @@ static int xenfb_connect_backend(struct xenbus_device *dev,
                xenbus_dev_fatal(dev, ret, "starting transaction");
                return ret;
        }
-       ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
-                           virt_to_mfn(info->page));
+       if (info->page_gref < 0)
+               ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
+                                   virt_to_mfn(info->page));
+       else
+               ret = xenbus_printf(xbt, dev->nodename, "page-gref", "%u",
+                                   info->page_gref);
        if (ret)
                goto error_xenbus;
        ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
-- 
1.7.3.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel