forked from Minki/linux
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>
This commit is contained in:
parent
8c3c283e6b
commit
0a4dfa5ddb
@ -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);
|
||||
@ -232,15 +230,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;
|
||||
|
||||
@ -248,10 +251,13 @@ 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",
|
||||
@ -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);
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user