The vkbd device should be able to use a grant reference to map the shared page.
Signed-off-by: Owen smith <owen.sm...@citrix.com> --- hw/display/xenfb.c | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index 2c39753..c4375c8 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -54,6 +54,7 @@ struct common { struct XenDevice xendev; /* must be first */ void *page; + int page_gref; QemuConsole *con; }; @@ -96,22 +97,36 @@ static int common_bind(struct common *c) { uint64_t mfn; - if (xenstore_read_fe_uint64(&c->xendev, "page-ref", &mfn) == -1) - return -1; - assert(mfn == (xen_pfn_t)mfn); - if (xenstore_read_fe_int(&c->xendev, "event-channel", &c->xendev.remote_port) == -1) return -1; - c->page = xc_map_foreign_range(xen_xc, c->xendev.dom, - XC_PAGE_SIZE, - PROT_READ | PROT_WRITE, mfn); + if (xenstore_read_fe_uint64(&c->xendev, "page-ref", &mfn) == -1) { + if (xenstore_read_fe_int(&c->xendev, "page-gref", &c->page_gref) == -1) { + return -1; + } + c->page = xc_gnttab_map_grant_ref(c->xendev.gnttabdev, + c->xendev.dom, + c->page_gref, + PROT_READ | PROT_WRITE); + } else { + assert(mfn == (xen_pfn_t)mfn); + + c->page = xc_map_foreign_range(xen_xc, c->xendev.dom, + XC_PAGE_SIZE, + PROT_READ | PROT_WRITE, mfn); + } if (c->page == NULL) return -1; xen_be_bind_evtchn(&c->xendev); - xen_be_printf(&c->xendev, 1, "ring mfn %"PRIx64", remote-port %d, local-port %d\n", - mfn, c->xendev.remote_port, c->xendev.local_port); + + if (c->page_gref) { + xen_be_printf(&c->xendev, 1, "ring gref %d, remote-port %d, local-port %d\n", + c->page_gref, c->xendev.remote_port, c->xendev.local_port); + } else { + xen_be_printf(&c->xendev, 1, "ring mfn %"PRIx64", remote-port %d, local-port %d\n", + mfn, c->xendev.remote_port, c->xendev.local_port); + } return 0; } @@ -120,8 +135,13 @@ static void common_unbind(struct common *c) { xen_be_unbind_evtchn(&c->xendev); if (c->page) { - munmap(c->page, XC_PAGE_SIZE); + if (c->page_gref) { + xc_gnttab_munmap(c->xendev.gnttabdev, c->page, 1); + } else { + munmap(c->page, XC_PAGE_SIZE); + } c->page = NULL; + c->page_gref = 0; } } @@ -954,6 +974,7 @@ static void fb_event(struct XenDevice *xendev) struct XenDevOps xen_kbdmouse_ops = { .size = sizeof(struct XenInput), + .flags = DEVOPS_FLAG_NEED_GNTDEV, .init = input_init, .initialise = input_initialise, .connected = input_connected, -- 2.1.0