|
@@ -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");
|