Skip to content

Commit

Permalink
Input: xen-kbdfront - add grant reference for shared page
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Daniel De Graaf authored and Dmitry Torokhov committed Mar 17, 2011
1 parent 8c3c283 commit 0a4dfa5
Showing 1 changed file with 28 additions and 11 deletions.
39 changes: 28 additions & 11 deletions drivers/input/xen-kbdfront.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
Expand All @@ -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];
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -232,26 +230,34 @@ 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;

again:
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",
Expand All @@ -263,7 +269,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);
Expand All @@ -272,6 +278,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;
}

Expand All @@ -280,6 +294,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,
Expand Down

0 comments on commit 0a4dfa5

Please sign in to comment.