static int common_bind(struct common *c) { uint64_t val; xen_pfn_t mfn; if (xenstore_read_fe_uint64(&c->xendev, "page-ref", &val) == -1) return -1; mfn = (xen_pfn_t)val; assert(val == mfn); if (xenstore_read_fe_int(&c->xendev, "event-channel", &c->xendev.remote_port) == -1) return -1; c->page = xenforeignmemory_map(xen_fmem, c->xendev.dom, PROT_READ | PROT_WRITE, 1, &mfn, NULL); if (c->page == NULL) return -1; xen_be_bind_evtchn(&c->xendev); xen_pv_printf(&c->xendev, 1, "ring mfn %"PRI_xen_pfn", remote-port %d, local-port %d\n", mfn, c->xendev.remote_port, c->xendev.local_port); return 0; }
static int con_initialise(struct XenDevice *xendev) { struct XenConsole *con = container_of(xendev, struct XenConsole, xendev); int limit; if (xenstore_read_int(con->console, "ring-ref", &con->ring_ref) == -1) return -1; if (xenstore_read_int(con->console, "port", &con->xendev.remote_port) == -1) return -1; if (xenstore_read_int(con->console, "limit", &limit) == 0) con->buffer.max_capacity = limit; if (!xendev->dev) { xen_pfn_t mfn = con->ring_ref; con->sring = xenforeignmemory_map(xen_fmem, con->xendev.dom, PROT_READ|PROT_WRITE, 1, &mfn, NULL); } else { con->sring = xengnttab_map_grant_ref(xendev->gnttabdev, con->xendev.dom, con->ring_ref, PROT_READ|PROT_WRITE); } if (!con->sring) return -1; xen_be_bind_evtchn(&con->xendev); qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive, xencons_receive, NULL, NULL, con, NULL, true); xen_pv_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n", con->ring_ref, con->xendev.remote_port, con->xendev.local_port, con->buffer.max_capacity); return 0; }
static int xenfb_map_fb(struct XenFB *xenfb) { struct xenfb_page *page = xenfb->c.page; char *protocol = xenfb->c.xendev.protocol; int n_fbdirs; xen_pfn_t *pgmfns = NULL; xen_pfn_t *fbmfns = NULL; void *map, *pd; int mode, ret = -1; /* default to native */ pd = page->pd; mode = sizeof(unsigned long) * 8; if (!protocol) { /* * Undefined protocol, some guesswork needed. * * Old frontends which don't set the protocol use * one page directory only, thus pd[1] must be zero. * pd[1] of the 32bit struct layout and the lower * 32 bits of pd[0] of the 64bit struct layout have * the same location, so we can check that ... */ uint32_t *ptr32 = NULL; uint32_t *ptr64 = NULL; #if defined(__i386__) ptr32 = (void*)page->pd; ptr64 = ((void*)page->pd) + 4; #elif defined(__x86_64__) ptr32 = ((void*)page->pd) - 4; ptr64 = (void*)page->pd; #endif if (ptr32) { if (ptr32[1] == 0) { mode = 32; pd = ptr32; } else { mode = 64; pd = ptr64; } } #if defined(__x86_64__) } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_32) == 0) { /* 64bit dom0, 32bit domU */ mode = 32; pd = ((void*)page->pd) - 4; #elif defined(__i386__) } else if (strcmp(protocol, XEN_IO_PROTO_ABI_X86_64) == 0) { /* 32bit dom0, 64bit domU */ mode = 64; pd = ((void*)page->pd) + 4; #endif } if (xenfb->pixels) { munmap(xenfb->pixels, xenfb->fbpages * XC_PAGE_SIZE); xenfb->pixels = NULL; } xenfb->fbpages = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE; n_fbdirs = xenfb->fbpages * mode / 8; n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE; pgmfns = g_malloc0(sizeof(xen_pfn_t) * n_fbdirs); fbmfns = g_malloc0(sizeof(xen_pfn_t) * xenfb->fbpages); xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd); map = xenforeignmemory_map(xen_fmem, xenfb->c.xendev.dom, PROT_READ, n_fbdirs, pgmfns, NULL); if (map == NULL) goto out; xenfb_copy_mfns(mode, xenfb->fbpages, fbmfns, map); xenforeignmemory_unmap(xen_fmem, map, n_fbdirs); xenfb->pixels = xenforeignmemory_map(xen_fmem, xenfb->c.xendev.dom, PROT_READ, xenfb->fbpages, fbmfns, NULL); if (xenfb->pixels == NULL) goto out; ret = 0; /* all is fine */ out: g_free(pgmfns); g_free(fbmfns); return ret; }