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

[Xen-devel] [PATCH 3/3] xen-kbdfront: Add grant reference for shared page



Without a grant reference, full access to the domain's memory is
required to use the shared page. Add an additional parameter in
xenstore to allow grant mapping to be used.

Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
---
 drivers/input/xen-kbdfront.c |   39 ++++++++++++++++++++++++++++-----------
 1 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c
index 7f85a86..a5c064e 100644
--- a/drivers/input/xen-kbdfront.c
+++ b/drivers/input/xen-kbdfront.c
@@ -11,12 +11,6 @@
  *  more details.
  */
 
-/*
- * TODO:
- *
- * Switch to grant tables together with xen-fbfront.c.
- */
-
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
@@ -30,6 +24,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/kbdif.h>
 #include <xen/xenbus.h>
@@ -38,6 +34,7 @@ struct xenkbd_info {
        struct input_dev *kbd;
        struct input_dev *ptr;
        struct xenkbd_page *page;
+       int gref;
        int irq;
        struct xenbus_device *xbdev;
        char phys[32];
@@ -122,6 +119,7 @@ static int __devinit xenkbd_probe(struct xenbus_device *dev,
        dev_set_drvdata(&dev->dev, info);
        info->xbdev = dev;
        info->irq = -1;
+       info->gref = -1;
        snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename);
 
        info->page = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
@@ -218,15 +216,20 @@ static int xenkbd_connect_backend(struct xenbus_device 
*dev,
        int ret, evtchn;
        struct xenbus_transaction xbt;
 
+       ret = gnttab_grant_foreign_access(dev->otherend_id,
+                                         virt_to_mfn(info->page), 0);
+       if (ret < 0)
+               return ret;
+       info->gref = ret;
+
        ret = xenbus_alloc_evtchn(dev, &evtchn);
        if (ret)
-               return ret;
+               goto error_grant;
        ret = bind_evtchn_to_irqhandler(evtchn, input_handler,
                                        0, dev->devicetype, info);
        if (ret < 0) {
-               xenbus_free_evtchn(dev, evtchn);
                xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler");
-               return ret;
+               goto error_evtchan;
        }
        info->irq = ret;
 
@@ -234,12 +237,15 @@ static int xenkbd_connect_backend(struct xenbus_device 
*dev,
        ret = xenbus_transaction_start(&xbt);
        if (ret) {
                xenbus_dev_fatal(dev, ret, "starting transaction");
-               return ret;
+               goto error_irqh;
        }
        ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
                            virt_to_mfn(info->page));
        if (ret)
                goto error_xenbus;
+       ret = xenbus_printf(xbt, dev->nodename, "page-gref", "%u", info->gref);
+       if (ret)
+               goto error_xenbus;
        ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
                            evtchn);
        if (ret)
@@ -249,7 +255,7 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
                if (ret == -EAGAIN)
                        goto again;
                xenbus_dev_fatal(dev, ret, "completing transaction");
-               return ret;
+               goto error_irqh;
        }
 
        xenbus_switch_state(dev, XenbusStateInitialised);
@@ -258,6 +264,14 @@ static int xenkbd_connect_backend(struct xenbus_device 
*dev,
  error_xenbus:
        xenbus_transaction_end(xbt, 1);
        xenbus_dev_fatal(dev, ret, "writing xenstore");
+ error_irqh:
+       unbind_from_irqhandler(info->irq, info);
+       info->irq = -1;
+ error_evtchan:
+       xenbus_free_evtchn(dev, evtchn);
+ error_grant:
+       gnttab_end_foreign_access_ref(info->gref, 0);
+       info->gref = -1;
        return ret;
 }
 
@@ -266,6 +280,9 @@ static void xenkbd_disconnect_backend(struct xenkbd_info 
*info)
        if (info->irq >= 0)
                unbind_from_irqhandler(info->irq, info);
        info->irq = -1;
+       if (info->gref >= 0)
+               gnttab_end_foreign_access_ref(info->gref, 0);
+       info->gref = -1;
 }
 
 static void xenkbd_backend_changed(struct xenbus_device *dev,
-- 
1.7.3.4


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


 


Rackspace

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