@@ -947,7 +947,7 @@ static void xen_device_frontend_destroy(XenDevice *xendev)
void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
Error **errp)
{
- if (xengnttab_set_max_grants(xendev->xgth, nr_refs)) {
+ if (qemu_xen_gnttab_set_max_grants(xendev->xgth, nr_refs)) {
error_setg_errno(errp, errno, "xengnttab_set_max_grants failed");
}
}
@@ -956,9 +956,8 @@ void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
unsigned int nr_refs, int prot,
Error **errp)
{
- void *map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_refs,
- xendev->frontend_id, refs,
- prot);
+ void *map = qemu_xen_gnttab_map_refs(xendev->xgth, nr_refs,
+ xendev->frontend_id, refs, prot);
if (!map) {
error_setg_errno(errp, errno,
@@ -971,109 +970,17 @@ void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
void xen_device_unmap_grant_refs(XenDevice *xendev, void *map,
unsigned int nr_refs, Error **errp)
{
- if (xengnttab_unmap(xendev->xgth, map, nr_refs)) {
+ if (qemu_xen_gnttab_unmap(xendev->xgth, map, nr_refs)) {
error_setg_errno(errp, errno, "xengnttab_unmap failed");
}
}
-static void compat_copy_grant_refs(XenDevice *xendev, bool to_domain,
- XenDeviceGrantCopySegment segs[],
- unsigned int nr_segs, Error **errp)
-{
- uint32_t *refs = g_new(uint32_t, nr_segs);
- int prot = to_domain ? PROT_WRITE : PROT_READ;
- void *map;
- unsigned int i;
-
- for (i = 0; i < nr_segs; i++) {
- XenDeviceGrantCopySegment *seg = &segs[i];
-
- refs[i] = to_domain ? seg->dest.foreign.ref :
- seg->source.foreign.ref;
- }
-
- map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_segs,
- xendev->frontend_id, refs,
- prot);
- if (!map) {
- error_setg_errno(errp, errno,
- "xengnttab_map_domain_grant_refs failed");
- goto done;
- }
-
- for (i = 0; i < nr_segs; i++) {
- XenDeviceGrantCopySegment *seg = &segs[i];
- void *page = map + (i * XC_PAGE_SIZE);
-
- if (to_domain) {
- memcpy(page + seg->dest.foreign.offset, seg->source.virt,
- seg->len);
- } else {
- memcpy(seg->dest.virt, page + seg->source.foreign.offset,
- seg->len);
- }
- }
-
- if (xengnttab_unmap(xendev->xgth, map, nr_segs)) {
- error_setg_errno(errp, errno, "xengnttab_unmap failed");
- }
-
-done:
- g_free(refs);
-}
-
void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
XenDeviceGrantCopySegment segs[],
unsigned int nr_segs, Error **errp)
{
- xengnttab_grant_copy_segment_t *xengnttab_segs;
- unsigned int i;
-
- if (!xendev->feature_grant_copy) {
- compat_copy_grant_refs(xendev, to_domain, segs, nr_segs, errp);
- return;
- }
-
- xengnttab_segs = g_new0(xengnttab_grant_copy_segment_t, nr_segs);
-
- for (i = 0; i < nr_segs; i++) {
- XenDeviceGrantCopySegment *seg = &segs[i];
- xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i];
-
- if (to_domain) {
- xengnttab_seg->flags = GNTCOPY_dest_gref;
- xengnttab_seg->dest.foreign.domid = xendev->frontend_id;
- xengnttab_seg->dest.foreign.ref = seg->dest.foreign.ref;
- xengnttab_seg->dest.foreign.offset = seg->dest.foreign.offset;
- xengnttab_seg->source.virt = seg->source.virt;
- } else {
- xengnttab_seg->flags = GNTCOPY_source_gref;
- xengnttab_seg->source.foreign.domid = xendev->frontend_id;
- xengnttab_seg->source.foreign.ref = seg->source.foreign.ref;
- xengnttab_seg->source.foreign.offset =
- seg->source.foreign.offset;
- xengnttab_seg->dest.virt = seg->dest.virt;
- }
-
- xengnttab_seg->len = seg->len;
- }
-
- if (xengnttab_grant_copy(xendev->xgth, nr_segs, xengnttab_segs)) {
- error_setg_errno(errp, errno, "xengnttab_grant_copy failed");
- goto done;
- }
-
- for (i = 0; i < nr_segs; i++) {
- xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i];
-
- if (xengnttab_seg->status != GNTST_okay) {
- error_setg(errp, "xengnttab_grant_copy seg[%u] failed", i);
- break;
- }
- }
-
-done:
- g_free(xengnttab_segs);
+ qemu_xen_gnttab_grant_copy(xendev->xgth, to_domain, xendev->frontend_id,
+ (XenGrantCopySegment *)segs, nr_segs, errp);
}
struct XenEventChannel {
@@ -1235,7 +1142,7 @@ static void xen_device_unrealize(DeviceState *dev)
xen_device_backend_destroy(xendev);
if (xendev->xgth) {
- xengnttab_close(xendev->xgth);
+ qemu_xen_gnttab_close(xendev->xgth);
xendev->xgth = NULL;
}
@@ -1298,15 +1205,12 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
xendev->watch_list = watch_list_create(xendev->xsh);
- xendev->xgth = xengnttab_open(NULL, 0);
+ xendev->xgth = qemu_xen_gnttab_open();
if (!xendev->xgth) {
error_setg_errno(errp, errno, "failed xengnttab_open");
goto unrealize;
}
- xendev->feature_grant_copy =
- (xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0);
-
xen_device_backend_create(xendev, errp);
if (*errp) {
goto unrealize;
@@ -43,7 +43,6 @@ struct xs_handle *xenstore;
const char *xen_protocol;
/* private */
-static bool xen_feature_grant_copy;
static int debug;
int xenstore_write_be_str(struct XenLegacyDevice *xendev, const char *node,
@@ -113,7 +112,7 @@ void xen_be_set_max_grant_refs(struct XenLegacyDevice *xendev,
{
assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV);
- if (xengnttab_set_max_grants(xendev->gnttabdev, nr_refs)) {
+ if (qemu_xen_gnttab_set_max_grants(xendev->gnttabdev, nr_refs)) {
xen_pv_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n",
strerror(errno));
}
@@ -126,8 +125,8 @@ void *xen_be_map_grant_refs(struct XenLegacyDevice *xendev, uint32_t *refs,
assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV);
- ptr = xengnttab_map_domain_grant_refs(xendev->gnttabdev, nr_refs,
- xen_domid, refs, prot);
+ ptr = qemu_xen_gnttab_map_refs(xendev->gnttabdev, nr_refs, xen_domid, refs,
+ prot);
if (!ptr) {
xen_pv_printf(xendev, 0,
"xengnttab_map_domain_grant_refs failed: %s\n",
@@ -142,119 +141,27 @@ void xen_be_unmap_grant_refs(struct XenLegacyDevice *xendev, void *ptr,
{
assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV);
- if (xengnttab_unmap(xendev->gnttabdev, ptr, nr_refs)) {
+ if (qemu_xen_gnttab_unmap(xendev->gnttabdev, ptr, nr_refs)) {
xen_pv_printf(xendev, 0, "xengnttab_unmap failed: %s\n",
strerror(errno));
}
}
-static int compat_copy_grant_refs(struct XenLegacyDevice *xendev,
- bool to_domain,
- XenGrantCopySegment segs[],
- unsigned int nr_segs)
-{
- uint32_t *refs = g_new(uint32_t, nr_segs);
- int prot = to_domain ? PROT_WRITE : PROT_READ;
- void *pages;
- unsigned int i;
-
- for (i = 0; i < nr_segs; i++) {
- XenGrantCopySegment *seg = &segs[i];
-
- refs[i] = to_domain ?
- seg->dest.foreign.ref : seg->source.foreign.ref;
- }
-
- pages = xengnttab_map_domain_grant_refs(xendev->gnttabdev, nr_segs,
- xen_domid, refs, prot);
- if (!pages) {
- xen_pv_printf(xendev, 0,
- "xengnttab_map_domain_grant_refs failed: %s\n",
- strerror(errno));
- g_free(refs);
- return -1;
- }
-
- for (i = 0; i < nr_segs; i++) {
- XenGrantCopySegment *seg = &segs[i];
- void *page = pages + (i * XC_PAGE_SIZE);
-
- if (to_domain) {
- memcpy(page + seg->dest.foreign.offset, seg->source.virt,
- seg->len);
- } else {
- memcpy(seg->dest.virt, page + seg->source.foreign.offset,
- seg->len);
- }
- }
-
- if (xengnttab_unmap(xendev->gnttabdev, pages, nr_segs)) {
- xen_pv_printf(xendev, 0, "xengnttab_unmap failed: %s\n",
- strerror(errno));
- }
-
- g_free(refs);
- return 0;
-}
-
int xen_be_copy_grant_refs(struct XenLegacyDevice *xendev,
bool to_domain,
XenGrantCopySegment segs[],
unsigned int nr_segs)
{
- xengnttab_grant_copy_segment_t *xengnttab_segs;
- unsigned int i;
int rc;
assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV);
- if (!xen_feature_grant_copy) {
- return compat_copy_grant_refs(xendev, to_domain, segs, nr_segs);
- }
-
- xengnttab_segs = g_new0(xengnttab_grant_copy_segment_t, nr_segs);
-
- for (i = 0; i < nr_segs; i++) {
- XenGrantCopySegment *seg = &segs[i];
- xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i];
-
- if (to_domain) {
- xengnttab_seg->flags = GNTCOPY_dest_gref;
- xengnttab_seg->dest.foreign.domid = xen_domid;
- xengnttab_seg->dest.foreign.ref = seg->dest.foreign.ref;
- xengnttab_seg->dest.foreign.offset = seg->dest.foreign.offset;
- xengnttab_seg->source.virt = seg->source.virt;
- } else {
- xengnttab_seg->flags = GNTCOPY_source_gref;
- xengnttab_seg->source.foreign.domid = xen_domid;
- xengnttab_seg->source.foreign.ref = seg->source.foreign.ref;
- xengnttab_seg->source.foreign.offset =
- seg->source.foreign.offset;
- xengnttab_seg->dest.virt = seg->dest.virt;
- }
-
- xengnttab_seg->len = seg->len;
- }
-
- rc = xengnttab_grant_copy(xendev->gnttabdev, nr_segs, xengnttab_segs);
-
+ rc = qemu_xen_gnttab_grant_copy(xendev->gnttabdev, to_domain, xen_domid,
+ segs, nr_segs, NULL);
if (rc) {
- xen_pv_printf(xendev, 0, "xengnttab_copy failed: %s\n",
- strerror(errno));
- }
-
- for (i = 0; i < nr_segs; i++) {
- xengnttab_grant_copy_segment_t *xengnttab_seg =
- &xengnttab_segs[i];
-
- if (xengnttab_seg->status != GNTST_okay) {
- xen_pv_printf(xendev, 0, "segment[%u] status: %d\n", i,
- xengnttab_seg->status);
- rc = -1;
- }
+ xen_pv_printf(xendev, 0, "xengnttab_grant_copy failed: %s\n",
+ strerror(-rc));
}
-
- g_free(xengnttab_segs);
return rc;
}
@@ -466,7 +373,7 @@ static int xen_be_try_initialise(struct XenLegacyDevice *xendev)
}
if (xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
- xendev->gnttabdev = xengnttab_open(NULL, 0);
+ xendev->gnttabdev = qemu_xen_gnttab_open();
if (xendev->gnttabdev == NULL) {
xen_pv_printf(NULL, 0, "can't open gnttab device\n");
return -1;
@@ -524,7 +431,7 @@ static void xen_be_disconnect(struct XenLegacyDevice *xendev,
xendev->ops->disconnect(xendev);
}
if (xendev->gnttabdev) {
- xengnttab_close(xendev->gnttabdev);
+ qemu_xen_gnttab_close(xendev->gnttabdev);
xendev->gnttabdev = NULL;
}
if (xendev->be_state != state) {
@@ -687,8 +594,6 @@ static void xen_set_dynamic_sysbus(void)
void xen_be_init(void)
{
- xengnttab_handle *gnttabdev;
-
xenstore = xs_daemon_open();
if (!xenstore) {
xen_pv_printf(NULL, 0, "can't connect to xenstored\n");
@@ -697,19 +602,11 @@ void xen_be_init(void)
qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL);
- if (xen_xc == NULL || xen_fmem == NULL) {
+ if (xen_evtchn_ops == NULL || xen_gnttab_ops == NULL) {
xen_pv_printf(NULL, 0, "Xen operations not set up\n");
exit(1);
}
- gnttabdev = xengnttab_open(NULL, 0);
- if (gnttabdev != NULL) {
- if (xengnttab_grant_copy(gnttabdev, 0, NULL) == 0) {
- xen_feature_grant_copy = true;
- }
- xengnttab_close(gnttabdev);
- }
-
xen_sysdev = qdev_new(TYPE_XENSYSDEV);
sysbus_realize_and_unref(SYS_BUS_DEVICE(xen_sysdev), &error_fatal);
xen_sysbus = qbus_new(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus");
@@ -21,6 +21,7 @@
* must be undefined before including xenctrl.h
*/
#undef XC_WANT_COMPAT_EVTCHN_API
+#undef XC_WANT_COMPAT_GNTTAB_API
#include <xenctrl.h>
@@ -43,12 +44,141 @@ typedef evtchn_port_or_error_t xenevtchn_port_or_error_t;
#define xenevtchn_unmask(h, p) xc_evtchn_unmask(h, p)
#define xenevtchn_unbind(h, p) xc_evtchn_unbind(h, p)
+typedef xc_gnttab xengnttab_handle;
+
+#define xengnttab_open(l, f) xc_gnttab_open(l, f)
+#define xengnttab_close(h) xc_gnttab_close(h)
+#define xengnttab_set_max_grants(h, n) xc_gnttab_set_max_grants(h, n)
+#define xengnttab_map_grant_ref(h, d, r, p) xc_gnttab_map_grant_ref(h, d, r, p)
+#define xengnttab_unmap(h, a, n) xc_gnttab_munmap(h, a, n)
+#define xengnttab_map_grant_refs(h, c, d, r, p) \
+ xc_gnttab_map_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)
+
#else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >= 40701 */
#include <xenevtchn.h>
+#include <xengnttab.h>
#endif
+/* Xen before 4.8 */
+
+static int libxengnttab_fallback_grant_copy(xengnttab_handle *xgt,
+ bool to_domain, uint32_t domid,
+ XenGrantCopySegment segs[],
+ unsigned int nr_segs, Error **errp)
+{
+ uint32_t *refs = g_new(uint32_t, nr_segs);
+ int prot = to_domain ? PROT_WRITE : PROT_READ;
+ void *map;
+ unsigned int i;
+ int rc = 0;
+
+ for (i = 0; i < nr_segs; i++) {
+ XenGrantCopySegment *seg = &segs[i];
+
+ refs[i] = to_domain ? seg->dest.foreign.ref :
+ seg->source.foreign.ref;
+ }
+ map = xengnttab_map_domain_grant_refs(xgt, nr_segs, domid, refs, prot);
+ if (!map) {
+ if (errp) {
+ error_setg_errno(errp, errno,
+ "xengnttab_map_domain_grant_refs failed");
+ }
+ rc = -errno;
+ goto done;
+ }
+
+ for (i = 0; i < nr_segs; i++) {
+ XenGrantCopySegment *seg = &segs[i];
+ void *page = map + (i * XEN_PAGE_SIZE);
+
+ if (to_domain) {
+ memcpy(page + seg->dest.foreign.offset, seg->source.virt,
+ seg->len);
+ } else {
+ memcpy(seg->dest.virt, page + seg->source.foreign.offset,
+ seg->len);
+ }
+ }
+
+ if (xengnttab_unmap(xgt, map, nr_segs)) {
+ if (errp) {
+ error_setg_errno(errp, errno, "xengnttab_unmap failed");
+ }
+ rc = -errno;
+ }
+
+done:
+ g_free(refs);
+ return rc;
+}
+
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 40800
+
+static int libxengnttab_backend_grant_copy(xengnttab_handle *xgt,
+ bool to_domain, uint32_t domid,
+ XenGrantCopySegment *segs,
+ uint32_t nr_segs, Error **errp)
+{
+ xengnttab_grant_copy_segment_t *xengnttab_segs;
+ unsigned int i;
+ int rc;
+
+ xengnttab_segs = g_new0(xengnttab_grant_copy_segment_t, nr_segs);
+
+ for (i = 0; i < nr_segs; i++) {
+ XenGrantCopySegment *seg = &segs[i];
+ xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i];
+
+ if (to_domain) {
+ xengnttab_seg->flags = GNTCOPY_dest_gref;
+ xengnttab_seg->dest.foreign.domid = domid;
+ xengnttab_seg->dest.foreign.ref = seg->dest.foreign.ref;
+ xengnttab_seg->dest.foreign.offset = seg->dest.foreign.offset;
+ xengnttab_seg->source.virt = seg->source.virt;
+ } else {
+ xengnttab_seg->flags = GNTCOPY_source_gref;
+ xengnttab_seg->source.foreign.domid = domid;
+ xengnttab_seg->source.foreign.ref = seg->source.foreign.ref;
+ xengnttab_seg->source.foreign.offset =
+ seg->source.foreign.offset;
+ xengnttab_seg->dest.virt = seg->dest.virt;
+ }
+
+ xengnttab_seg->len = seg->len;
+ }
+
+ if (xengnttab_grant_copy(xgt, nr_segs, xengnttab_segs)) {
+ if (errp) {
+ error_setg_errno(errp, errno, "xengnttab_grant_copy failed");
+ }
+ rc = -errno;
+ goto done;
+ }
+
+ rc = 0;
+ for (i = 0; i < nr_segs; i++) {
+ xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i];
+
+ if (xengnttab_seg->status != GNTST_okay) {
+ if (errp) {
+ error_setg(errp, "xengnttab_grant_copy seg[%u] failed", i);
+ }
+ rc = -EIO;
+ break;
+ }
+ }
+
+done:
+ g_free(xengnttab_segs);
+ return rc;
+}
+#endif
+
static xenevtchn_handle *libxenevtchn_backend_open(void)
{
return xenevtchn_open(NULL, 0);
@@ -65,7 +195,34 @@ struct evtchn_backend_ops libxenevtchn_backend_ops = {
.pending = xenevtchn_pending,
};
+static xengnttab_handle *libxengnttab_backend_open(void)
+{
+ return xengnttab_open(NULL, 0);
+}
+
+
+static struct gnttab_backend_ops libxengnttab_backend_ops = {
+ .features = XEN_GNTTAB_OP_FEATURE_MAP_MULTIPLE,
+ .open = libxengnttab_backend_open,
+ .close = xengnttab_close,
+ .grant_copy = libxengnttab_fallback_grant_copy,
+ .set_max_grants = xengnttab_set_max_grants,
+ .map_refs = xengnttab_map_domain_grant_refs,
+ .unmap = xengnttab_unmap,
+};
+
void setup_xen_backend_ops(void)
{
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 40800
+ xengnttab_handle *xgt = xengnttab_open(NULL, 0);
+
+ if (xgt) {
+ if (xengnttab_grant_copy(xgt, 0, NULL) == 0) {
+ libxengnttab_backend_ops.grant_copy = libxengnttab_backend_grant_copy;
+ }
+ xengnttab_close(xgt);
+ }
+#endif
xen_evtchn_ops = &libxenevtchn_backend_ops;
+ xen_gnttab_ops = &libxengnttab_backend_ops;
}
@@ -309,7 +309,7 @@ void xen_pv_del_xendev(struct XenLegacyDevice *xendev)
qemu_xen_evtchn_close(xendev->evtchndev);
}
if (xendev->gnttabdev != NULL) {
- xengnttab_close(xendev->gnttabdev);
+ qemu_xen_gnttab_close(xendev->gnttabdev);
}
QTAILQ_REMOVE(&xendevs, xendev, next);
@@ -9,7 +9,7 @@
#define HW_XEN_BUS_H
#include "hw/xen/xen_backend_ops.h"
-#include "hw/xen/xen_common.h"
+#include "hw/xen/interface/io/xenbus.h"
#include "hw/sysbus.h"
#include "qemu/notify.h"
#include "qom/object.h"
@@ -33,7 +33,6 @@ struct XenDevice {
bool backend_online;
XenWatch *backend_online_watch;
xengnttab_handle *xgth;
- bool feature_grant_copy;
bool inactive;
QLIST_HEAD(, XenEventChannel) event_channels;
QLIST_ENTRY(XenDevice) list;
@@ -1,8 +1,8 @@
#ifndef HW_XEN_LEGACY_BACKEND_H
#define HW_XEN_LEGACY_BACKEND_H
-#include "hw/xen/xen_common.h"
#include "hw/xen/xen_backend_ops.h"
+#include "hw/xen/interface/io/xenbus.h"
#include "hw/xen/xen_pvdev.h"
#include "net/net.h"
#include "qom/object.h"
@@ -54,17 +54,6 @@ void *xen_be_map_grant_refs(struct XenLegacyDevice *xendev, uint32_t *refs,
void xen_be_unmap_grant_refs(struct XenLegacyDevice *xendev, void *ptr,
unsigned int nr_refs);
-typedef struct XenGrantCopySegment {
- union {
- void *virt;
- struct {
- uint32_t ref;
- off_t offset;
- } foreign;
- } source, dest;
- size_t len;
-} XenGrantCopySegment;
-
int xen_be_copy_grant_refs(struct XenLegacyDevice *xendev,
bool to_domain, XenGrantCopySegment segs[],
unsigned int nr_segs);
@@ -29,6 +29,12 @@
typedef struct xenevtchn_handle xenevtchn_handle;
typedef int xenevtchn_port_or_error_t;
typedef uint32_t evtchn_port_t;
+typedef uint16_t domid_t;
+typedef uint32_t grant_ref_t;
+
+#define XEN_PAGE_SHIFT 12
+#define XEN_PAGE_SIZE (1UL << XEN_PAGE_SHIFT)
+#define XEN_PAGE_MASK (~(XEN_PAGE_SIZE - 1))
struct evtchn_backend_ops {
xenevtchn_handle *(*open)(void);
@@ -113,6 +119,100 @@ static inline int qemu_xen_evtchn_pending(xenevtchn_handle *xc)
return xen_evtchn_ops->pending(xc);
}
+typedef struct xengntdev_handle xengnttab_handle;
+
+typedef struct XenGrantCopySegment {
+ union {
+ void *virt;
+ struct {
+ uint32_t ref;
+ off_t offset;
+ } foreign;
+ } source, dest;
+ size_t len;
+} XenGrantCopySegment;
+
+#define XEN_GNTTAB_OP_FEATURE_MAP_MULTIPLE (1U << 0)
+
+struct gnttab_backend_ops {
+ uint32_t features;
+ xengnttab_handle *(*open)(void);
+ int (*close)(xengnttab_handle *xgt);
+ int (*grant_copy)(xengnttab_handle *xgt, bool to_domain, uint32_t domid,
+ XenGrantCopySegment *segs, uint32_t nr_segs,
+ Error **errp);
+ int (*set_max_grants)(xengnttab_handle *xgt, uint32_t nr_grants);
+ void *(*map_refs)(xengnttab_handle *xgt, uint32_t count, uint32_t domid,
+ uint32_t *refs, int prot);
+ int (*unmap)(xengnttab_handle *xgt, void *start_address, uint32_t count);
+};
+
+extern struct gnttab_backend_ops *xen_gnttab_ops;
+
+static inline bool qemu_xen_gnttab_can_map_multi(void)
+{
+ return xen_gnttab_ops &&
+ !!(xen_gnttab_ops->features & XEN_GNTTAB_OP_FEATURE_MAP_MULTIPLE);
+}
+
+static inline xengnttab_handle *qemu_xen_gnttab_open(void)
+{
+ if (!xen_gnttab_ops) {
+ return NULL;
+ }
+ return xen_gnttab_ops->open();
+}
+
+static inline int qemu_xen_gnttab_close(xengnttab_handle *xgt)
+{
+ if (!xen_gnttab_ops) {
+ return -ENOSYS;
+ }
+ return xen_gnttab_ops->close(xgt);
+}
+
+static inline int qemu_xen_gnttab_grant_copy(xengnttab_handle *xgt,
+ bool to_domain, uint32_t domid,
+ XenGrantCopySegment *segs,
+ uint32_t nr_segs, Error **errp)
+{
+ if (!xen_gnttab_ops) {
+ return -ENOSYS;
+ }
+
+ return xen_gnttab_ops->grant_copy(xgt, to_domain, domid, segs, nr_segs,
+ errp);
+}
+
+static inline int qemu_xen_gnttab_set_max_grants(xengnttab_handle *xgt,
+ uint32_t nr_grants)
+{
+ if (!xen_gnttab_ops) {
+ return -ENOSYS;
+ }
+ return xen_gnttab_ops->set_max_grants(xgt, nr_grants);
+}
+
+static inline void *qemu_xen_gnttab_map_refs(xengnttab_handle *xgt,
+ uint32_t count, uint32_t domid,
+ uint32_t *refs, int prot)
+{
+ if (!xen_gnttab_ops) {
+ return NULL;
+ }
+ return xen_gnttab_ops->map_refs(xgt, count, domid, refs, prot);
+}
+
+static inline int qemu_xen_gnttab_unmap(xengnttab_handle *xgt,
+ void *start_address,
+ uint32_t count)
+{
+ if (!xen_gnttab_ops) {
+ return -ENOSYS;
+ }
+ return xen_gnttab_ops->unmap(xgt, start_address, count);
+}
+
void setup_xen_backend_ops(void);
#endif /* QEMU_XEN_BACKEND_OPS_H */
@@ -28,17 +28,6 @@ extern xc_interface *xen_xc;
#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 40701
typedef xc_interface xenforeignmemory_handle;
-typedef xc_gnttab xengnttab_handle;
-
-#define xengnttab_open(l, f) xc_gnttab_open(l, f)
-#define xengnttab_close(h) xc_gnttab_close(h)
-#define xengnttab_set_max_grants(h, n) xc_gnttab_set_max_grants(h, n)
-#define xengnttab_map_grant_ref(h, d, r, p) xc_gnttab_map_grant_ref(h, d, r, p)
-#define xengnttab_unmap(h, a, n) xc_gnttab_munmap(h, a, n)
-#define xengnttab_map_grant_refs(h, c, d, r, p) \
- xc_gnttab_map_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)
#define xenforeignmemory_open(l, f) xen_xc
#define xenforeignmemory_close(h)
@@ -58,7 +47,6 @@ static inline void *xenforeignmemory_map(xc_interface *h, uint32_t dom,
#else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >= 40701 */
-#include <xengnttab.h>
#include <xenforeignmemory.h>
#endif
@@ -648,31 +636,4 @@ static inline int xen_set_ioreq_server_state(domid_t dom,
#endif
-/* Xen before 4.8 */
-
-#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 40800
-
-struct xengnttab_grant_copy_segment {
- union xengnttab_copy_ptr {
- void *virt;
- struct {
- uint32_t ref;
- uint16_t offset;
- uint16_t domid;
- } foreign;
- } source, dest;
- uint16_t len;
- uint16_t flags;
- int16_t status;
-};
-
-typedef struct xengnttab_grant_copy_segment xengnttab_grant_copy_segment_t;
-
-static inline int xengnttab_grant_copy(xengnttab_handle *xgt, uint32_t count,
- xengnttab_grant_copy_segment_t *segs)
-{
- return -ENOSYS;
-}
-#endif
-
#endif /* QEMU_HW_XEN_COMMON_H */
@@ -66,3 +66,4 @@ uint32_t xen_domid;
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;