[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1300198274-1325-3-git-send-email-konrad.wilk@oracle.com>
Date: Tue, 15 Mar 2011 10:11:13 -0400
From: Konrad Rzeszutek Wilk <konrad.wilk@...cle.com>
To: linux-kernel@...r.kernel.org,
Jeremy Fitzhardinge <jeremy@...p.org>,
Dmitry Torokhov <dmitry.torokhov@...il.com>
Cc: xen-devel@...ts.xensource.com,
Konrad Rzeszutek Wilk <konrad@...nel.org>,
Stefano Stabellini <stefano.stabellini@...citrix.com>,
Ian Campbell <Ian.Campbell@...rix.com>, dgdegra@...ho.nsa.gov
Subject: [PATCH 2/4] xen-kbdfront: Add grant reference for shared page
From: Daniel De Graaf <dgdegra@...ho.nsa.gov>
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@...ho.nsa.gov>
Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@...cle.com>
Acked-by: Ian Campbell <Ian.Campbell@...citrix.com>
---
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.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists