hw/xen: Add foreignmem operations to allow redirection to internal emulation
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> Reviewed-by: Paul Durrant <paul@xen.org>
This commit is contained in:
parent
f80fad16af
commit
15e283c5b6
@ -237,9 +237,9 @@ static int con_initialise(struct XenLegacyDevice *xendev)
|
||||
|
||||
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);
|
||||
con->sring = qemu_xen_foreignmem_map(con->xendev.dom, NULL,
|
||||
PROT_READ | PROT_WRITE,
|
||||
1, &mfn, NULL);
|
||||
} else {
|
||||
con->sring = xen_be_map_grant_ref(xendev, con->ring_ref,
|
||||
PROT_READ | PROT_WRITE);
|
||||
@ -269,7 +269,7 @@ static void con_disconnect(struct XenLegacyDevice *xendev)
|
||||
|
||||
if (con->sring) {
|
||||
if (!xendev->dev) {
|
||||
xenforeignmemory_unmap(xen_fmem, con->sring, 1);
|
||||
qemu_xen_foreignmem_unmap(con->sring, 1);
|
||||
} else {
|
||||
xen_be_unmap_grant_ref(xendev, con->sring, con->ring_ref);
|
||||
}
|
||||
|
@ -98,8 +98,9 @@ static int common_bind(struct common *c)
|
||||
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);
|
||||
c->page = qemu_xen_foreignmem_map(c->xendev.dom, NULL,
|
||||
PROT_READ | PROT_WRITE, 1, &mfn,
|
||||
NULL);
|
||||
if (c->page == NULL)
|
||||
return -1;
|
||||
|
||||
@ -115,7 +116,7 @@ static void common_unbind(struct common *c)
|
||||
{
|
||||
xen_pv_unbind_evtchn(&c->xendev);
|
||||
if (c->page) {
|
||||
xenforeignmemory_unmap(xen_fmem, c->page, 1);
|
||||
qemu_xen_foreignmem_unmap(c->page, 1);
|
||||
c->page = NULL;
|
||||
}
|
||||
}
|
||||
@ -500,15 +501,16 @@ static int xenfb_map_fb(struct XenFB *xenfb)
|
||||
fbmfns = g_new0(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);
|
||||
map = qemu_xen_foreignmem_map(xenfb->c.xendev.dom, NULL, 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);
|
||||
qemu_xen_foreignmem_unmap(map, n_fbdirs);
|
||||
|
||||
xenfb->pixels = xenforeignmemory_map(xen_fmem, xenfb->c.xendev.dom,
|
||||
PROT_READ, xenfb->fbpages, fbmfns, NULL);
|
||||
xenfb->pixels = qemu_xen_foreignmem_map(xenfb->c.xendev.dom, NULL,
|
||||
PROT_READ, xenfb->fbpages,
|
||||
fbmfns, NULL);
|
||||
if (xenfb->pixels == NULL)
|
||||
goto out;
|
||||
|
||||
@ -927,7 +929,7 @@ static void fb_disconnect(struct XenLegacyDevice *xendev)
|
||||
* Replacing the framebuffer with anonymous shared memory
|
||||
* instead. This releases the guest pages and keeps qemu happy.
|
||||
*/
|
||||
xenforeignmemory_unmap(xen_fmem, fb->pixels, fb->fbpages);
|
||||
qemu_xen_foreignmem_unmap(fb->pixels, fb->fbpages);
|
||||
fb->pixels = mmap(fb->pixels, fb->fbpages * XC_PAGE_SIZE,
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON,
|
||||
-1, 0);
|
||||
|
@ -22,6 +22,7 @@
|
||||
*/
|
||||
#undef XC_WANT_COMPAT_EVTCHN_API
|
||||
#undef XC_WANT_COMPAT_GNTTAB_API
|
||||
#undef XC_WANT_COMPAT_MAP_FOREIGN_API
|
||||
|
||||
#include <xenctrl.h>
|
||||
|
||||
@ -56,10 +57,13 @@ typedef xc_gnttab xengnttab_handle;
|
||||
#define xengnttab_map_domain_grant_refs(h, c, d, r, p) \
|
||||
xc_gnttab_map_domain_grant_refs(h, c, d, r, p)
|
||||
|
||||
typedef xc_interface xenforeignmemory_handle;
|
||||
|
||||
#else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >= 40701 */
|
||||
|
||||
#include <xenevtchn.h>
|
||||
#include <xengnttab.h>
|
||||
#include <xenforeignmemory.h>
|
||||
|
||||
#endif
|
||||
|
||||
@ -218,6 +222,46 @@ static struct gnttab_backend_ops libxengnttab_backend_ops = {
|
||||
.unmap = libxengnttab_backend_unmap,
|
||||
};
|
||||
|
||||
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 40701
|
||||
|
||||
static void *libxenforeignmem_backend_map(uint32_t dom, void *addr, int prot,
|
||||
size_t pages, xfn_pfn_t *pfns,
|
||||
int *errs)
|
||||
{
|
||||
if (errs) {
|
||||
return xc_map_foreign_bulk(xen_xc, dom, prot, pfns, errs, pages);
|
||||
} else {
|
||||
return xc_map_foreign_pages(xen_xc, dom, prot, pfns, pages);
|
||||
}
|
||||
}
|
||||
|
||||
static int libxenforeignmem_backend_unmap(void *addr, size_t pages)
|
||||
{
|
||||
return munmap(addr, pages * XC_PAGE_SIZE);
|
||||
}
|
||||
|
||||
#else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >= 40701 */
|
||||
|
||||
static void *libxenforeignmem_backend_map(uint32_t dom, void *addr, int prot,
|
||||
size_t pages, xen_pfn_t *pfns,
|
||||
int *errs)
|
||||
{
|
||||
return xenforeignmemory_map2(xen_fmem, dom, addr, prot, 0, pages, pfns,
|
||||
errs);
|
||||
}
|
||||
|
||||
static int libxenforeignmem_backend_unmap(void *addr, size_t pages)
|
||||
{
|
||||
return xenforeignmemory_unmap(xen_fmem, addr, pages);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct foreignmem_backend_ops libxenforeignmem_backend_ops = {
|
||||
.map = libxenforeignmem_backend_map,
|
||||
.unmap = libxenforeignmem_backend_unmap,
|
||||
};
|
||||
|
||||
void setup_xen_backend_ops(void)
|
||||
{
|
||||
#if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 40800
|
||||
@ -232,4 +276,5 @@ void setup_xen_backend_ops(void)
|
||||
#endif
|
||||
xen_evtchn_ops = &libxenevtchn_backend_ops;
|
||||
xen_gnttab_ops = &libxengnttab_backend_ops;
|
||||
xen_foreignmem_ops = &libxenforeignmem_backend_ops;
|
||||
}
|
||||
|
@ -214,6 +214,32 @@ static inline int qemu_xen_gnttab_unmap(xengnttab_handle *xgt,
|
||||
return xen_gnttab_ops->unmap(xgt, start_address, refs, count);
|
||||
}
|
||||
|
||||
struct foreignmem_backend_ops {
|
||||
void *(*map)(uint32_t dom, void *addr, int prot, size_t pages,
|
||||
xen_pfn_t *pfns, int *errs);
|
||||
int (*unmap)(void *addr, size_t pages);
|
||||
};
|
||||
|
||||
extern struct foreignmem_backend_ops *xen_foreignmem_ops;
|
||||
|
||||
static inline void *qemu_xen_foreignmem_map(uint32_t dom, void *addr, int prot,
|
||||
size_t pages, xen_pfn_t *pfns,
|
||||
int *errs)
|
||||
{
|
||||
if (!xen_foreignmem_ops) {
|
||||
return NULL;
|
||||
}
|
||||
return xen_foreignmem_ops->map(dom, addr, prot, pages, pfns, errs);
|
||||
}
|
||||
|
||||
static inline int qemu_xen_foreignmem_unmap(void *addr, size_t pages)
|
||||
{
|
||||
if (!xen_foreignmem_ops) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
return xen_foreignmem_ops->unmap(addr, pages);
|
||||
}
|
||||
|
||||
void setup_xen_backend_ops(void);
|
||||
|
||||
#endif /* QEMU_XEN_BACKEND_OPS_H */
|
||||
|
@ -32,19 +32,6 @@ typedef xc_interface xenforeignmemory_handle;
|
||||
#define xenforeignmemory_open(l, f) xen_xc
|
||||
#define xenforeignmemory_close(h)
|
||||
|
||||
static inline void *xenforeignmemory_map(xc_interface *h, uint32_t dom,
|
||||
int prot, size_t pages,
|
||||
const xen_pfn_t arr[/*pages*/],
|
||||
int err[/*pages*/])
|
||||
{
|
||||
if (err)
|
||||
return xc_map_foreign_bulk(h, dom, prot, arr, err, pages);
|
||||
else
|
||||
return xc_map_foreign_pages(h, dom, prot, arr, pages);
|
||||
}
|
||||
|
||||
#define xenforeignmemory_unmap(h, p, s) munmap(p, s * XC_PAGE_SIZE)
|
||||
|
||||
#else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >= 40701 */
|
||||
|
||||
#include <xenforeignmemory.h>
|
||||
|
@ -67,3 +67,4 @@ enum xen_mode xen_mode = XEN_DISABLED;
|
||||
bool xen_domid_restrict;
|
||||
struct evtchn_backend_ops *xen_evtchn_ops;
|
||||
struct gnttab_backend_ops *xen_gnttab_ops;
|
||||
struct foreignmem_backend_ops *xen_foreignmem_ops;
|
||||
|
@ -23,6 +23,7 @@ static GList *xs_node_list;
|
||||
* doesn't hurt).
|
||||
*/
|
||||
#define __XEN_PUBLIC_XEN_H__
|
||||
typedef unsigned long xen_pfn_t;
|
||||
|
||||
#include "hw/i386/kvm/xenstore_impl.c"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user