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 | |
| 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')
| -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, |
