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) {
|
if (!xendev->dev) {
|
||||||
xen_pfn_t mfn = con->ring_ref;
|
xen_pfn_t mfn = con->ring_ref;
|
||||||
con->sring = xenforeignmemory_map(xen_fmem, con->xendev.dom,
|
con->sring = qemu_xen_foreignmem_map(con->xendev.dom, NULL,
|
||||||
PROT_READ | PROT_WRITE,
|
PROT_READ | PROT_WRITE,
|
||||||
1, &mfn, NULL);
|
1, &mfn, NULL);
|
||||||
} else {
|
} else {
|
||||||
con->sring = xen_be_map_grant_ref(xendev, con->ring_ref,
|
con->sring = xen_be_map_grant_ref(xendev, con->ring_ref,
|
||||||
PROT_READ | PROT_WRITE);
|
PROT_READ | PROT_WRITE);
|
||||||
@ -269,7 +269,7 @@ static void con_disconnect(struct XenLegacyDevice *xendev)
|
|||||||
|
|
||||||
if (con->sring) {
|
if (con->sring) {
|
||||||
if (!xendev->dev) {
|
if (!xendev->dev) {
|
||||||
xenforeignmemory_unmap(xen_fmem, con->sring, 1);
|
qemu_xen_foreignmem_unmap(con->sring, 1);
|
||||||
} else {
|
} else {
|
||||||
xen_be_unmap_grant_ref(xendev, con->sring, con->ring_ref);
|
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)
|
if (xenstore_read_fe_int(&c->xendev, "event-channel", &c->xendev.remote_port) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
c->page = xenforeignmemory_map(xen_fmem, c->xendev.dom,
|
c->page = qemu_xen_foreignmem_map(c->xendev.dom, NULL,
|
||||||
PROT_READ | PROT_WRITE, 1, &mfn, NULL);
|
PROT_READ | PROT_WRITE, 1, &mfn,
|
||||||
|
NULL);
|
||||||
if (c->page == NULL)
|
if (c->page == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -115,7 +116,7 @@ static void common_unbind(struct common *c)
|
|||||||
{
|
{
|
||||||
xen_pv_unbind_evtchn(&c->xendev);
|
xen_pv_unbind_evtchn(&c->xendev);
|
||||||
if (c->page) {
|
if (c->page) {
|
||||||
xenforeignmemory_unmap(xen_fmem, c->page, 1);
|
qemu_xen_foreignmem_unmap(c->page, 1);
|
||||||
c->page = NULL;
|
c->page = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -500,15 +501,16 @@ static int xenfb_map_fb(struct XenFB *xenfb)
|
|||||||
fbmfns = g_new0(xen_pfn_t, xenfb->fbpages);
|
fbmfns = g_new0(xen_pfn_t, xenfb->fbpages);
|
||||||
|
|
||||||
xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
|
xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
|
||||||
map = xenforeignmemory_map(xen_fmem, xenfb->c.xendev.dom,
|
map = qemu_xen_foreignmem_map(xenfb->c.xendev.dom, NULL, PROT_READ,
|
||||||
PROT_READ, n_fbdirs, pgmfns, NULL);
|
n_fbdirs, pgmfns, NULL);
|
||||||
if (map == NULL)
|
if (map == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
xenfb_copy_mfns(mode, xenfb->fbpages, fbmfns, map);
|
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,
|
xenfb->pixels = qemu_xen_foreignmem_map(xenfb->c.xendev.dom, NULL,
|
||||||
PROT_READ, xenfb->fbpages, fbmfns, NULL);
|
PROT_READ, xenfb->fbpages,
|
||||||
|
fbmfns, NULL);
|
||||||
if (xenfb->pixels == NULL)
|
if (xenfb->pixels == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -927,7 +929,7 @@ static void fb_disconnect(struct XenLegacyDevice *xendev)
|
|||||||
* Replacing the framebuffer with anonymous shared memory
|
* Replacing the framebuffer with anonymous shared memory
|
||||||
* instead. This releases the guest pages and keeps qemu happy.
|
* 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,
|
fb->pixels = mmap(fb->pixels, fb->fbpages * XC_PAGE_SIZE,
|
||||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON,
|
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON,
|
||||||
-1, 0);
|
-1, 0);
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
#undef XC_WANT_COMPAT_EVTCHN_API
|
#undef XC_WANT_COMPAT_EVTCHN_API
|
||||||
#undef XC_WANT_COMPAT_GNTTAB_API
|
#undef XC_WANT_COMPAT_GNTTAB_API
|
||||||
|
#undef XC_WANT_COMPAT_MAP_FOREIGN_API
|
||||||
|
|
||||||
#include <xenctrl.h>
|
#include <xenctrl.h>
|
||||||
|
|
||||||
@ -56,10 +57,13 @@ typedef xc_gnttab xengnttab_handle;
|
|||||||
#define xengnttab_map_domain_grant_refs(h, c, d, r, p) \
|
#define xengnttab_map_domain_grant_refs(h, c, d, r, p) \
|
||||||
xc_gnttab_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 */
|
#else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >= 40701 */
|
||||||
|
|
||||||
#include <xenevtchn.h>
|
#include <xenevtchn.h>
|
||||||
#include <xengnttab.h>
|
#include <xengnttab.h>
|
||||||
|
#include <xenforeignmemory.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -218,6 +222,46 @@ static struct gnttab_backend_ops libxengnttab_backend_ops = {
|
|||||||
.unmap = libxengnttab_backend_unmap,
|
.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)
|
void setup_xen_backend_ops(void)
|
||||||
{
|
{
|
||||||
#if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 40800
|
#if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 40800
|
||||||
@ -232,4 +276,5 @@ void setup_xen_backend_ops(void)
|
|||||||
#endif
|
#endif
|
||||||
xen_evtchn_ops = &libxenevtchn_backend_ops;
|
xen_evtchn_ops = &libxenevtchn_backend_ops;
|
||||||
xen_gnttab_ops = &libxengnttab_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);
|
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);
|
void setup_xen_backend_ops(void);
|
||||||
|
|
||||||
#endif /* QEMU_XEN_BACKEND_OPS_H */
|
#endif /* QEMU_XEN_BACKEND_OPS_H */
|
||||||
|
@ -32,19 +32,6 @@ typedef xc_interface xenforeignmemory_handle;
|
|||||||
#define xenforeignmemory_open(l, f) xen_xc
|
#define xenforeignmemory_open(l, f) xen_xc
|
||||||
#define xenforeignmemory_close(h)
|
#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 */
|
#else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >= 40701 */
|
||||||
|
|
||||||
#include <xenforeignmemory.h>
|
#include <xenforeignmemory.h>
|
||||||
|
@ -67,3 +67,4 @@ enum xen_mode xen_mode = XEN_DISABLED;
|
|||||||
bool xen_domid_restrict;
|
bool xen_domid_restrict;
|
||||||
struct evtchn_backend_ops *xen_evtchn_ops;
|
struct evtchn_backend_ops *xen_evtchn_ops;
|
||||||
struct gnttab_backend_ops *xen_gnttab_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).
|
* doesn't hurt).
|
||||||
*/
|
*/
|
||||||
#define __XEN_PUBLIC_XEN_H__
|
#define __XEN_PUBLIC_XEN_H__
|
||||||
|
typedef unsigned long xen_pfn_t;
|
||||||
|
|
||||||
#include "hw/i386/kvm/xenstore_impl.c"
|
#include "hw/i386/kvm/xenstore_impl.c"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user