aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorDaniel De Graaf <dgdegra@tycho.nsa.gov>2011-03-17 01:52:42 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-03-17 02:24:07 -0400
commit0a4dfa5ddb5fc0aff331e255da282b01a74a6cd3 (patch)
tree8621e773958d1ceedbdf4d81b43d0aeac634797d /drivers/input
parent8c3c283e6bf463ab498d6e7823aff6c4762314b6 (diff)
Input: 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@tycho.nsa.gov> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/xen-kbdfront.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c
index 53e62732ee96..7077f9bf5ead 100644
--- a/drivers/input/xen-kbdfront.c
+++ b/drivers/input/xen-kbdfront.c
@@ -11,12 +11,6 @@
11 * more details. 11 * more details.
12 */ 12 */
13 13
14/*
15 * TODO:
16 *
17 * Switch to grant tables together with xen-fbfront.c.
18 */
19
20#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21 15
22#include <linux/kernel.h> 16#include <linux/kernel.h>
@@ -30,6 +24,8 @@
30#include <xen/xen.h> 24#include <xen/xen.h>
31#include <xen/events.h> 25#include <xen/events.h>
32#include <xen/page.h> 26#include <xen/page.h>
27#include <xen/grant_table.h>
28#include <xen/interface/grant_table.h>
33#include <xen/interface/io/fbif.h> 29#include <xen/interface/io/fbif.h>
34#include <xen/interface/io/kbdif.h> 30#include <xen/interface/io/kbdif.h>
35#include <xen/xenbus.h> 31#include <xen/xenbus.h>
@@ -38,6 +34,7 @@ struct xenkbd_info {
38 struct input_dev *kbd; 34 struct input_dev *kbd;
39 struct input_dev *ptr; 35 struct input_dev *ptr;
40 struct xenkbd_page *page; 36 struct xenkbd_page *page;
37 int gref;
41 int irq; 38 int irq;
42 struct xenbus_device *xbdev; 39 struct xenbus_device *xbdev;
43 char phys[32]; 40 char phys[32];
@@ -122,6 +119,7 @@ static int __devinit xenkbd_probe(struct xenbus_device *dev,
122 dev_set_drvdata(&dev->dev, info); 119 dev_set_drvdata(&dev->dev, info);
123 info->xbdev = dev; 120 info->xbdev = dev;
124 info->irq = -1; 121 info->irq = -1;
122 info->gref = -1;
125 snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename); 123 snprintf(info->phys, sizeof(info->phys), "xenbus/%s", dev->nodename);
126 124
127 info->page = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); 125 info->page = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
@@ -232,15 +230,20 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
232 int ret, evtchn; 230 int ret, evtchn;
233 struct xenbus_transaction xbt; 231 struct xenbus_transaction xbt;
234 232
233 ret = gnttab_grant_foreign_access(dev->otherend_id,
234 virt_to_mfn(info->page), 0);
235 if (ret < 0)
236 return ret;
237 info->gref = ret;
238
235 ret = xenbus_alloc_evtchn(dev, &evtchn); 239 ret = xenbus_alloc_evtchn(dev, &evtchn);
236 if (ret) 240 if (ret)
237 return ret; 241 goto error_grant;
238 ret = bind_evtchn_to_irqhandler(evtchn, input_handler, 242 ret = bind_evtchn_to_irqhandler(evtchn, input_handler,
239 0, dev->devicetype, info); 243 0, dev->devicetype, info);
240 if (ret < 0) { 244 if (ret < 0) {
241 xenbus_free_evtchn(dev, evtchn);
242 xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler"); 245 xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler");
243 return ret; 246 goto error_evtchan;
244 } 247 }
245 info->irq = ret; 248 info->irq = ret;
246 249
@@ -248,12 +251,15 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
248 ret = xenbus_transaction_start(&xbt); 251 ret = xenbus_transaction_start(&xbt);
249 if (ret) { 252 if (ret) {
250 xenbus_dev_fatal(dev, ret, "starting transaction"); 253 xenbus_dev_fatal(dev, ret, "starting transaction");
251 return ret; 254 goto error_irqh;
252 } 255 }
253 ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu", 256 ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu",
254 virt_to_mfn(info->page)); 257 virt_to_mfn(info->page));
255 if (ret) 258 if (ret)
256 goto error_xenbus; 259 goto error_xenbus;
260 ret = xenbus_printf(xbt, dev->nodename, "page-gref", "%u", info->gref);
261 if (ret)
262 goto error_xenbus;
257 ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u", 263 ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
258 evtchn); 264 evtchn);
259 if (ret) 265 if (ret)
@@ -263,7 +269,7 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
263 if (ret == -EAGAIN) 269 if (ret == -EAGAIN)
264 goto again; 270 goto again;
265 xenbus_dev_fatal(dev, ret, "completing transaction"); 271 xenbus_dev_fatal(dev, ret, "completing transaction");
266 return ret; 272 goto error_irqh;
267 } 273 }
268 274
269 xenbus_switch_state(dev, XenbusStateInitialised); 275 xenbus_switch_state(dev, XenbusStateInitialised);
@@ -272,6 +278,14 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
272 error_xenbus: 278 error_xenbus:
273 xenbus_transaction_end(xbt, 1); 279 xenbus_transaction_end(xbt, 1);
274 xenbus_dev_fatal(dev, ret, "writing xenstore"); 280 xenbus_dev_fatal(dev, ret, "writing xenstore");
281 error_irqh:
282 unbind_from_irqhandler(info->irq, info);
283 info->irq = -1;
284 error_evtchan:
285 xenbus_free_evtchn(dev, evtchn);
286 error_grant:
287 gnttab_end_foreign_access_ref(info->gref, 0);
288 info->gref = -1;
275 return ret; 289 return ret;
276} 290}
277 291
@@ -280,6 +294,9 @@ static void xenkbd_disconnect_backend(struct xenkbd_info *info)
280 if (info->irq >= 0) 294 if (info->irq >= 0)
281 unbind_from_irqhandler(info->irq, info); 295 unbind_from_irqhandler(info->irq, info);
282 info->irq = -1; 296 info->irq = -1;
297 if (info->gref >= 0)
298 gnttab_end_foreign_access_ref(info->gref, 0);
299 info->gref = -1;
283} 300}
284 301
285static void xenkbd_backend_changed(struct xenbus_device *dev, 302static void xenkbd_backend_changed(struct xenbus_device *dev,