diff options
author | Daniel De Graaf <dgdegra@tycho.nsa.gov> | 2011-03-17 01:52:42 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-03-17 02:24:07 -0400 |
commit | 0a4dfa5ddb5fc0aff331e255da282b01a74a6cd3 (patch) | |
tree | 8621e773958d1ceedbdf4d81b43d0aeac634797d /drivers/input/xen-kbdfront.c | |
parent | 8c3c283e6bf463ab498d6e7823aff6c4762314b6 (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/xen-kbdfront.c')
-rw-r--r-- | 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 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 | ||
285 | static void xenkbd_backend_changed(struct xenbus_device *dev, | 302 | static void xenkbd_backend_changed(struct xenbus_device *dev, |