Xen 2016/10/28
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJYE/VuAAoJEIlPj0hw4a6Q/qAP+gMhunO/OJRSwIlYSOt+fVKW LE17QUfdVe204IuWY3h9svTvJXj/pOsE1HtIrGAUwsJxMqMBHeZnKhVZvEbvL2Iy sKSxzQkkPa6qVn/+Nxr9ZxULJZPXWnl61FLbElelff4w46lTaBM3gBaWDekFEO64 RbMvsMAUmav1x88KPvqY71Crbx5wbPhNmFqhbJNaQmm3zIQDK1TzGESv882mQKy2 rKNapBUXq8XnUNN+lIHhnzU9kUjhZxu7uet3GHMVICeAYu3b9jkgomv2OcV/sfRg 3o/NoXp4I7ZY3F0fkbtJOIFx0m+YlWnQhkBGsQoXJW+4lUdQR9ypMY4OdzjRa80e w9GrDt1//LOYrTpB0ZBkW0MIfnUK4TCqtL/aEQtRY9fdRFvcVpCjnqrYw+u9boZ1 hVypTYmAbk/ece6aJ/dngDQVtGC9qMGlHtBqSBRajFxenvFdY+DK6/FhITpNmobU YPWTSwS6WPw/venfvrTMfCQudGW3Jg8iBzRbGPS+GYfYlTHFoO0lKFGWWeTuRFIw /4owDhMJr5hRMRWZxCAu+Z8Ymj1MFuK7zDKjvT9LgWOZORh+rz6Tfn9+oxSt/D9I 1VKb/T9N9wBS3kreZ+Uz5+aQBoQSN5AQjay2ECZ16u9i63EL89CqXyyrJLlKlEGB cP3GzM9DlAtCQR943bys =Ao+X -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/sstabellini/tags/xen-20161028-tag' into staging Xen 2016/10/28 # gpg: Signature made Sat 29 Oct 2016 02:03:42 BST # gpg: using RSA key 0x894F8F4870E1AE90 # gpg: Good signature from "Stefano Stabellini <sstabellini@kernel.org>" # gpg: aka "Stefano Stabellini <stefano.stabellini@eu.citrix.com>" # Primary key fingerprint: D04E 33AB A51F 67BA 07D3 0AEA 894F 8F48 70E1 AE90 * remotes/sstabellini/tags/xen-20161028-tag: xen: Rename xen_be_del_xendev xen: Rename xen_be_find_xendev xen: Rename xen_be_evtchn_event xen: Rename xen_be_send_notify xen: Rename xen_be_unbind_evtchn xen: Rename xen_be_printf to xen_pv_printf xen: Move xenstore cleanup and mkdir functions xen: Prepare xendev qtail to be shared with frontends xen: Move evtchn functions to xen_pvdev.c xen: Move xenstore_update to xen_pvdev.c xen: Create a new file xen_pvdev.c xen: Fix coding style warnings xen: Fix coding style errors Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
5ff06787d4
|
@ -167,12 +167,12 @@ static void destroy_grant(gpointer pgnt)
|
||||||
xengnttab_handle *gnt = grant->blkdev->xendev.gnttabdev;
|
xengnttab_handle *gnt = grant->blkdev->xendev.gnttabdev;
|
||||||
|
|
||||||
if (xengnttab_unmap(gnt, grant->page, 1) != 0) {
|
if (xengnttab_unmap(gnt, grant->page, 1) != 0) {
|
||||||
xen_be_printf(&grant->blkdev->xendev, 0,
|
xen_pv_printf(&grant->blkdev->xendev, 0,
|
||||||
"xengnttab_unmap failed: %s\n",
|
"xengnttab_unmap failed: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
grant->blkdev->persistent_gnt_count--;
|
grant->blkdev->persistent_gnt_count--;
|
||||||
xen_be_printf(&grant->blkdev->xendev, 3,
|
xen_pv_printf(&grant->blkdev->xendev, 3,
|
||||||
"unmapped grant %p\n", grant->page);
|
"unmapped grant %p\n", grant->page);
|
||||||
g_free(grant);
|
g_free(grant);
|
||||||
}
|
}
|
||||||
|
@ -184,11 +184,11 @@ static void remove_persistent_region(gpointer data, gpointer dev)
|
||||||
xengnttab_handle *gnt = blkdev->xendev.gnttabdev;
|
xengnttab_handle *gnt = blkdev->xendev.gnttabdev;
|
||||||
|
|
||||||
if (xengnttab_unmap(gnt, region->addr, region->num) != 0) {
|
if (xengnttab_unmap(gnt, region->addr, region->num) != 0) {
|
||||||
xen_be_printf(&blkdev->xendev, 0,
|
xen_pv_printf(&blkdev->xendev, 0,
|
||||||
"xengnttab_unmap region %p failed: %s\n",
|
"xengnttab_unmap region %p failed: %s\n",
|
||||||
region->addr, strerror(errno));
|
region->addr, strerror(errno));
|
||||||
}
|
}
|
||||||
xen_be_printf(&blkdev->xendev, 3,
|
xen_pv_printf(&blkdev->xendev, 3,
|
||||||
"unmapped grant region %p with %d pages\n",
|
"unmapped grant region %p with %d pages\n",
|
||||||
region->addr, region->num);
|
region->addr, region->num);
|
||||||
g_free(region);
|
g_free(region);
|
||||||
|
@ -255,7 +255,7 @@ static int ioreq_parse(struct ioreq *ioreq)
|
||||||
size_t len;
|
size_t len;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
xen_be_printf(&blkdev->xendev, 3,
|
xen_pv_printf(&blkdev->xendev, 3,
|
||||||
"op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
|
"op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
|
||||||
ioreq->req.operation, ioreq->req.nr_segments,
|
ioreq->req.operation, ioreq->req.nr_segments,
|
||||||
ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
|
ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
|
||||||
|
@ -275,28 +275,28 @@ static int ioreq_parse(struct ioreq *ioreq)
|
||||||
case BLKIF_OP_DISCARD:
|
case BLKIF_OP_DISCARD:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n",
|
xen_pv_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n",
|
||||||
ioreq->req.operation);
|
ioreq->req.operation);
|
||||||
goto err;
|
goto err;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
|
if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
|
||||||
xen_be_printf(&blkdev->xendev, 0, "error: write req for ro device\n");
|
xen_pv_printf(&blkdev->xendev, 0, "error: write req for ro device\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
|
ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
|
||||||
for (i = 0; i < ioreq->req.nr_segments; i++) {
|
for (i = 0; i < ioreq->req.nr_segments; i++) {
|
||||||
if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
|
if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
|
||||||
xen_be_printf(&blkdev->xendev, 0, "error: nr_segments too big\n");
|
xen_pv_printf(&blkdev->xendev, 0, "error: nr_segments too big\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
|
if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
|
||||||
xen_be_printf(&blkdev->xendev, 0, "error: first > last sector\n");
|
xen_pv_printf(&blkdev->xendev, 0, "error: first > last sector\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
|
if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
|
||||||
xen_be_printf(&blkdev->xendev, 0, "error: page crossing\n");
|
xen_pv_printf(&blkdev->xendev, 0, "error: page crossing\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +308,7 @@ static int ioreq_parse(struct ioreq *ioreq)
|
||||||
qemu_iovec_add(&ioreq->v, (void*)mem, len);
|
qemu_iovec_add(&ioreq->v, (void*)mem, len);
|
||||||
}
|
}
|
||||||
if (ioreq->start + ioreq->v.size > blkdev->file_size) {
|
if (ioreq->start + ioreq->v.size > blkdev->file_size) {
|
||||||
xen_be_printf(&blkdev->xendev, 0, "error: access beyond end of file\n");
|
xen_pv_printf(&blkdev->xendev, 0, "error: access beyond end of file\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -331,7 +331,7 @@ static void ioreq_unmap(struct ioreq *ioreq)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (xengnttab_unmap(gnt, ioreq->pages, ioreq->num_unmap) != 0) {
|
if (xengnttab_unmap(gnt, ioreq->pages, ioreq->num_unmap) != 0) {
|
||||||
xen_be_printf(&ioreq->blkdev->xendev, 0,
|
xen_pv_printf(&ioreq->blkdev->xendev, 0,
|
||||||
"xengnttab_unmap failed: %s\n",
|
"xengnttab_unmap failed: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
@ -343,7 +343,7 @@ static void ioreq_unmap(struct ioreq *ioreq)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (xengnttab_unmap(gnt, ioreq->page[i], 1) != 0) {
|
if (xengnttab_unmap(gnt, ioreq->page[i], 1) != 0) {
|
||||||
xen_be_printf(&ioreq->blkdev->xendev, 0,
|
xen_pv_printf(&ioreq->blkdev->xendev, 0,
|
||||||
"xengnttab_unmap failed: %s\n",
|
"xengnttab_unmap failed: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
|
@ -381,7 +381,7 @@ static int ioreq_map(struct ioreq *ioreq)
|
||||||
|
|
||||||
if (grant != NULL) {
|
if (grant != NULL) {
|
||||||
page[i] = grant->page;
|
page[i] = grant->page;
|
||||||
xen_be_printf(&ioreq->blkdev->xendev, 3,
|
xen_pv_printf(&ioreq->blkdev->xendev, 3,
|
||||||
"using persistent-grant %" PRIu32 "\n",
|
"using persistent-grant %" PRIu32 "\n",
|
||||||
ioreq->refs[i]);
|
ioreq->refs[i]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -410,7 +410,7 @@ static int ioreq_map(struct ioreq *ioreq)
|
||||||
ioreq->pages = xengnttab_map_grant_refs
|
ioreq->pages = xengnttab_map_grant_refs
|
||||||
(gnt, new_maps, domids, refs, ioreq->prot);
|
(gnt, new_maps, domids, refs, ioreq->prot);
|
||||||
if (ioreq->pages == NULL) {
|
if (ioreq->pages == NULL) {
|
||||||
xen_be_printf(&ioreq->blkdev->xendev, 0,
|
xen_pv_printf(&ioreq->blkdev->xendev, 0,
|
||||||
"can't map %d grant refs (%s, %d maps)\n",
|
"can't map %d grant refs (%s, %d maps)\n",
|
||||||
new_maps, strerror(errno), ioreq->blkdev->cnt_map);
|
new_maps, strerror(errno), ioreq->blkdev->cnt_map);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -426,7 +426,7 @@ static int ioreq_map(struct ioreq *ioreq)
|
||||||
ioreq->page[i] = xengnttab_map_grant_ref
|
ioreq->page[i] = xengnttab_map_grant_ref
|
||||||
(gnt, domids[i], refs[i], ioreq->prot);
|
(gnt, domids[i], refs[i], ioreq->prot);
|
||||||
if (ioreq->page[i] == NULL) {
|
if (ioreq->page[i] == NULL) {
|
||||||
xen_be_printf(&ioreq->blkdev->xendev, 0,
|
xen_pv_printf(&ioreq->blkdev->xendev, 0,
|
||||||
"can't map grant ref %d (%s, %d maps)\n",
|
"can't map grant ref %d (%s, %d maps)\n",
|
||||||
refs[i], strerror(errno), ioreq->blkdev->cnt_map);
|
refs[i], strerror(errno), ioreq->blkdev->cnt_map);
|
||||||
ioreq->mapped = 1;
|
ioreq->mapped = 1;
|
||||||
|
@ -474,7 +474,7 @@ static int ioreq_map(struct ioreq *ioreq)
|
||||||
grant->page = ioreq->page[new_maps];
|
grant->page = ioreq->page[new_maps];
|
||||||
}
|
}
|
||||||
grant->blkdev = ioreq->blkdev;
|
grant->blkdev = ioreq->blkdev;
|
||||||
xen_be_printf(&ioreq->blkdev->xendev, 3,
|
xen_pv_printf(&ioreq->blkdev->xendev, 3,
|
||||||
"adding grant %" PRIu32 " page: %p\n",
|
"adding grant %" PRIu32 " page: %p\n",
|
||||||
refs[new_maps], grant->page);
|
refs[new_maps], grant->page);
|
||||||
g_tree_insert(ioreq->blkdev->persistent_gnts,
|
g_tree_insert(ioreq->blkdev->persistent_gnts,
|
||||||
|
@ -557,7 +557,7 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
|
||||||
rc = xengnttab_grant_copy(gnt, count, segs);
|
rc = xengnttab_grant_copy(gnt, count, segs);
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
xen_be_printf(&ioreq->blkdev->xendev, 0,
|
xen_pv_printf(&ioreq->blkdev->xendev, 0,
|
||||||
"failed to copy data %d\n", rc);
|
"failed to copy data %d\n", rc);
|
||||||
ioreq->aio_errors++;
|
ioreq->aio_errors++;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -565,7 +565,7 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
if (segs[i].status != GNTST_okay) {
|
if (segs[i].status != GNTST_okay) {
|
||||||
xen_be_printf(&ioreq->blkdev->xendev, 3,
|
xen_pv_printf(&ioreq->blkdev->xendev, 3,
|
||||||
"failed to copy data %d for gref %d, domid %d\n",
|
"failed to copy data %d for gref %d, domid %d\n",
|
||||||
segs[i].status, ioreq->refs[i], ioreq->domids[i]);
|
segs[i].status, ioreq->refs[i], ioreq->domids[i]);
|
||||||
ioreq->aio_errors++;
|
ioreq->aio_errors++;
|
||||||
|
@ -599,7 +599,7 @@ static void qemu_aio_complete(void *opaque, int ret)
|
||||||
struct ioreq *ioreq = opaque;
|
struct ioreq *ioreq = opaque;
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
xen_be_printf(&ioreq->blkdev->xendev, 0, "%s I/O error\n",
|
xen_pv_printf(&ioreq->blkdev->xendev, 0, "%s I/O error\n",
|
||||||
ioreq->req.operation == BLKIF_OP_READ ? "read" : "write");
|
ioreq->req.operation == BLKIF_OP_READ ? "read" : "write");
|
||||||
ioreq->aio_errors++;
|
ioreq->aio_errors++;
|
||||||
}
|
}
|
||||||
|
@ -796,7 +796,7 @@ static void blk_send_response_all(struct XenBlkDev *blkdev)
|
||||||
ioreq_release(ioreq, true);
|
ioreq_release(ioreq, true);
|
||||||
}
|
}
|
||||||
if (send_notify) {
|
if (send_notify) {
|
||||||
xen_be_send_notify(&blkdev->xendev);
|
xen_pv_send_notify(&blkdev->xendev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -866,7 +866,7 @@ static void blk_handle_requests(struct XenBlkDev *blkdev)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (blk_send_response_one(ioreq)) {
|
if (blk_send_response_one(ioreq)) {
|
||||||
xen_be_send_notify(&blkdev->xendev);
|
xen_pv_send_notify(&blkdev->xendev);
|
||||||
}
|
}
|
||||||
ioreq_release(ioreq, false);
|
ioreq_release(ioreq, false);
|
||||||
continue;
|
continue;
|
||||||
|
@ -910,7 +910,7 @@ static void blk_alloc(struct XenDevice *xendev)
|
||||||
}
|
}
|
||||||
if (xengnttab_set_max_grants(xendev->gnttabdev,
|
if (xengnttab_set_max_grants(xendev->gnttabdev,
|
||||||
MAX_GRANTS(max_requests, BLKIF_MAX_SEGMENTS_PER_REQUEST)) < 0) {
|
MAX_GRANTS(max_requests, BLKIF_MAX_SEGMENTS_PER_REQUEST)) < 0) {
|
||||||
xen_be_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n",
|
xen_pv_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1056,11 +1056,11 @@ static int blk_connect(struct XenDevice *xendev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup via xenbus -> create new block driver instance */
|
/* setup via xenbus -> create new block driver instance */
|
||||||
xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
|
xen_pv_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
|
||||||
blkdev->blk = blk_new_open(blkdev->filename, NULL, options,
|
blkdev->blk = blk_new_open(blkdev->filename, NULL, options,
|
||||||
qflags, &local_err);
|
qflags, &local_err);
|
||||||
if (!blkdev->blk) {
|
if (!blkdev->blk) {
|
||||||
xen_be_printf(&blkdev->xendev, 0, "error: %s\n",
|
xen_pv_printf(&blkdev->xendev, 0, "error: %s\n",
|
||||||
error_get_pretty(local_err));
|
error_get_pretty(local_err));
|
||||||
error_free(local_err);
|
error_free(local_err);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1068,10 +1068,11 @@ static int blk_connect(struct XenDevice *xendev)
|
||||||
blk_set_enable_write_cache(blkdev->blk, !writethrough);
|
blk_set_enable_write_cache(blkdev->blk, !writethrough);
|
||||||
} else {
|
} else {
|
||||||
/* setup via qemu cmdline -> already setup for us */
|
/* setup via qemu cmdline -> already setup for us */
|
||||||
xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");
|
xen_pv_printf(&blkdev->xendev, 2,
|
||||||
|
"get configured bdrv (cmdline setup)\n");
|
||||||
blkdev->blk = blk_by_legacy_dinfo(blkdev->dinfo);
|
blkdev->blk = blk_by_legacy_dinfo(blkdev->dinfo);
|
||||||
if (blk_is_read_only(blkdev->blk) && !readonly) {
|
if (blk_is_read_only(blkdev->blk) && !readonly) {
|
||||||
xen_be_printf(&blkdev->xendev, 0, "Unexpected read-only drive");
|
xen_pv_printf(&blkdev->xendev, 0, "Unexpected read-only drive");
|
||||||
blkdev->blk = NULL;
|
blkdev->blk = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1084,13 +1085,13 @@ static int blk_connect(struct XenDevice *xendev)
|
||||||
if (blkdev->file_size < 0) {
|
if (blkdev->file_size < 0) {
|
||||||
BlockDriverState *bs = blk_bs(blkdev->blk);
|
BlockDriverState *bs = blk_bs(blkdev->blk);
|
||||||
const char *drv_name = bs ? bdrv_get_format_name(bs) : NULL;
|
const char *drv_name = bs ? bdrv_get_format_name(bs) : NULL;
|
||||||
xen_be_printf(&blkdev->xendev, 1, "blk_getlength: %d (%s) | drv %s\n",
|
xen_pv_printf(&blkdev->xendev, 1, "blk_getlength: %d (%s) | drv %s\n",
|
||||||
(int)blkdev->file_size, strerror(-blkdev->file_size),
|
(int)blkdev->file_size, strerror(-blkdev->file_size),
|
||||||
drv_name ?: "-");
|
drv_name ?: "-");
|
||||||
blkdev->file_size = 0;
|
blkdev->file_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
|
xen_pv_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
|
||||||
" size %" PRId64 " (%" PRId64 " MB)\n",
|
" size %" PRId64 " (%" PRId64 " MB)\n",
|
||||||
blkdev->type, blkdev->fileproto, blkdev->filename,
|
blkdev->type, blkdev->fileproto, blkdev->filename,
|
||||||
blkdev->file_size, blkdev->file_size >> 20);
|
blkdev->file_size, blkdev->file_size >> 20);
|
||||||
|
@ -1174,10 +1175,10 @@ static int blk_connect(struct XenDevice *xendev)
|
||||||
blkdev->feature_grant_copy =
|
blkdev->feature_grant_copy =
|
||||||
(xengnttab_grant_copy(blkdev->xendev.gnttabdev, 0, NULL) == 0);
|
(xengnttab_grant_copy(blkdev->xendev.gnttabdev, 0, NULL) == 0);
|
||||||
|
|
||||||
xen_be_printf(&blkdev->xendev, 3, "grant copy operation %s\n",
|
xen_pv_printf(&blkdev->xendev, 3, "grant copy operation %s\n",
|
||||||
blkdev->feature_grant_copy ? "enabled" : "disabled");
|
blkdev->feature_grant_copy ? "enabled" : "disabled");
|
||||||
|
|
||||||
xen_be_printf(&blkdev->xendev, 1, "ok: proto %s, ring-ref %d, "
|
xen_pv_printf(&blkdev->xendev, 1, "ok: proto %s, ring-ref %d, "
|
||||||
"remote port %d, local port %d\n",
|
"remote port %d, local port %d\n",
|
||||||
blkdev->xendev.protocol, blkdev->ring_ref,
|
blkdev->xendev.protocol, blkdev->ring_ref,
|
||||||
blkdev->xendev.remote_port, blkdev->xendev.local_port);
|
blkdev->xendev.remote_port, blkdev->xendev.local_port);
|
||||||
|
@ -1193,7 +1194,7 @@ static void blk_disconnect(struct XenDevice *xendev)
|
||||||
blk_unref(blkdev->blk);
|
blk_unref(blkdev->blk);
|
||||||
blkdev->blk = NULL;
|
blkdev->blk = NULL;
|
||||||
}
|
}
|
||||||
xen_be_unbind_evtchn(&blkdev->xendev);
|
xen_pv_unbind_evtchn(&blkdev->xendev);
|
||||||
|
|
||||||
if (blkdev->sring) {
|
if (blkdev->sring) {
|
||||||
xengnttab_unmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
|
xengnttab_unmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
|
||||||
|
|
|
@ -74,7 +74,7 @@ static void buffer_append(struct XenConsole *con)
|
||||||
|
|
||||||
xen_mb();
|
xen_mb();
|
||||||
intf->out_cons = cons;
|
intf->out_cons = cons;
|
||||||
xen_be_send_notify(&con->xendev);
|
xen_pv_send_notify(&con->xendev);
|
||||||
|
|
||||||
if (buffer->max_capacity &&
|
if (buffer->max_capacity &&
|
||||||
buffer->size > buffer->max_capacity) {
|
buffer->size > buffer->max_capacity) {
|
||||||
|
@ -142,7 +142,7 @@ static void xencons_receive(void *opaque, const uint8_t *buf, int len)
|
||||||
}
|
}
|
||||||
xen_wmb();
|
xen_wmb();
|
||||||
intf->in_prod = prod;
|
intf->in_prod = prod;
|
||||||
xen_be_send_notify(&con->xendev);
|
xen_pv_send_notify(&con->xendev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xencons_send(struct XenConsole *con)
|
static void xencons_send(struct XenConsole *con)
|
||||||
|
@ -158,16 +158,17 @@ static void xencons_send(struct XenConsole *con)
|
||||||
len = size;
|
len = size;
|
||||||
}
|
}
|
||||||
if (len < 1) {
|
if (len < 1) {
|
||||||
if (!con->backlog) {
|
if (!con->backlog) {
|
||||||
con->backlog = 1;
|
con->backlog = 1;
|
||||||
xen_be_printf(&con->xendev, 1, "backlog piling up, nobody listening?\n");
|
xen_pv_printf(&con->xendev, 1,
|
||||||
}
|
"backlog piling up, nobody listening?\n");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
buffer_advance(&con->buffer, len);
|
buffer_advance(&con->buffer, len);
|
||||||
if (con->backlog && len == size) {
|
if (con->backlog && len == size) {
|
||||||
con->backlog = 0;
|
con->backlog = 0;
|
||||||
xen_be_printf(&con->xendev, 1, "backlog is gone\n");
|
xen_pv_printf(&con->xendev, 1, "backlog is gone\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +192,7 @@ static int con_init(struct XenDevice *xendev)
|
||||||
|
|
||||||
type = xenstore_read_str(con->console, "type");
|
type = xenstore_read_str(con->console, "type");
|
||||||
if (!type || strcmp(type, "ioemu") != 0) {
|
if (!type || strcmp(type, "ioemu") != 0) {
|
||||||
xen_be_printf(xendev, 1, "not for me (type=%s)\n", type);
|
xen_pv_printf(xendev, 1, "not for me (type=%s)\n", type);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -247,7 +248,8 @@ static int con_initialise(struct XenDevice *xendev)
|
||||||
qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive,
|
qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive,
|
||||||
xencons_receive, NULL, con, NULL, true);
|
xencons_receive, NULL, con, NULL, true);
|
||||||
|
|
||||||
xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n",
|
xen_pv_printf(xendev, 1,
|
||||||
|
"ring mfn %d, remote port %d, local port %d, limit %zd\n",
|
||||||
con->ring_ref,
|
con->ring_ref,
|
||||||
con->xendev.remote_port,
|
con->xendev.remote_port,
|
||||||
con->xendev.local_port,
|
con->xendev.local_port,
|
||||||
|
@ -260,7 +262,7 @@ static void con_disconnect(struct XenDevice *xendev)
|
||||||
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
|
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
|
||||||
|
|
||||||
qemu_chr_fe_deinit(&con->chr);
|
qemu_chr_fe_deinit(&con->chr);
|
||||||
xen_be_unbind_evtchn(&con->xendev);
|
xen_pv_unbind_evtchn(&con->xendev);
|
||||||
|
|
||||||
if (con->sring) {
|
if (con->sring) {
|
||||||
if (!xendev->dev) {
|
if (!xendev->dev) {
|
||||||
|
|
|
@ -90,28 +90,29 @@ static int common_bind(struct common *c)
|
||||||
xen_pfn_t mfn;
|
xen_pfn_t mfn;
|
||||||
|
|
||||||
if (xenstore_read_fe_uint64(&c->xendev, "page-ref", &val) == -1)
|
if (xenstore_read_fe_uint64(&c->xendev, "page-ref", &val) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
mfn = (xen_pfn_t)val;
|
mfn = (xen_pfn_t)val;
|
||||||
assert(val == mfn);
|
assert(val == mfn);
|
||||||
|
|
||||||
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 = xenforeignmemory_map(xen_fmem, c->xendev.dom,
|
||||||
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;
|
||||||
|
|
||||||
xen_be_bind_evtchn(&c->xendev);
|
xen_be_bind_evtchn(&c->xendev);
|
||||||
xen_be_printf(&c->xendev, 1, "ring mfn %"PRI_xen_pfn", remote-port %d, local-port %d\n",
|
xen_pv_printf(&c->xendev, 1,
|
||||||
mfn, c->xendev.remote_port, c->xendev.local_port);
|
"ring mfn %"PRI_xen_pfn", remote-port %d, local-port %d\n",
|
||||||
|
mfn, c->xendev.remote_port, c->xendev.local_port);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void common_unbind(struct common *c)
|
static void common_unbind(struct common *c)
|
||||||
{
|
{
|
||||||
xen_be_unbind_evtchn(&c->xendev);
|
xen_pv_unbind_evtchn(&c->xendev);
|
||||||
if (c->page) {
|
if (c->page) {
|
||||||
xenforeignmemory_unmap(xen_fmem, c->page, 1);
|
xenforeignmemory_unmap(xen_fmem, c->page, 1);
|
||||||
c->page = NULL;
|
c->page = NULL;
|
||||||
|
@ -214,7 +215,7 @@ static int xenfb_kbd_event(struct XenInput *xenfb,
|
||||||
XENKBD_IN_RING_REF(page, prod) = *event;
|
XENKBD_IN_RING_REF(page, prod) = *event;
|
||||||
xen_wmb(); /* ensure ring contents visible */
|
xen_wmb(); /* ensure ring contents visible */
|
||||||
page->in_prod = prod + 1;
|
page->in_prod = prod + 1;
|
||||||
return xen_be_send_notify(&xenfb->c.xendev);
|
return xen_pv_send_notify(&xenfb->c.xendev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send a keyboard (or mouse button) event */
|
/* Send a keyboard (or mouse button) event */
|
||||||
|
@ -345,7 +346,7 @@ static int input_initialise(struct XenDevice *xendev)
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!in->c.con) {
|
if (!in->c.con) {
|
||||||
xen_be_printf(xendev, 1, "ds not set (yet)\n");
|
xen_pv_printf(xendev, 1, "ds not set (yet)\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +397,7 @@ static void input_event(struct XenDevice *xendev)
|
||||||
if (page->out_prod == page->out_cons)
|
if (page->out_prod == page->out_cons)
|
||||||
return;
|
return;
|
||||||
page->out_cons = page->out_prod;
|
page->out_cons = page->out_prod;
|
||||||
xen_be_send_notify(&xenfb->c.xendev);
|
xen_pv_send_notify(&xenfb->c.xendev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -500,8 +501,8 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim,
|
static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim,
|
||||||
int width, int height, int depth,
|
int width, int height, int depth,
|
||||||
size_t fb_len, int offset, int row_stride)
|
size_t fb_len, int offset, int row_stride)
|
||||||
{
|
{
|
||||||
size_t mfn_sz = sizeof(*((struct xenfb_page *)0)->pd);
|
size_t mfn_sz = sizeof(*((struct xenfb_page *)0)->pd);
|
||||||
size_t pd_len = sizeof(((struct xenfb_page *)0)->pd) / mfn_sz;
|
size_t pd_len = sizeof(((struct xenfb_page *)0)->pd) / mfn_sz;
|
||||||
|
@ -510,40 +511,47 @@ static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim,
|
||||||
int max_width, max_height;
|
int max_width, max_height;
|
||||||
|
|
||||||
if (fb_len_lim > fb_len_max) {
|
if (fb_len_lim > fb_len_max) {
|
||||||
xen_be_printf(&xenfb->c.xendev, 0, "fb size limit %zu exceeds %zu, corrected\n",
|
xen_pv_printf(&xenfb->c.xendev, 0,
|
||||||
fb_len_lim, fb_len_max);
|
"fb size limit %zu exceeds %zu, corrected\n",
|
||||||
fb_len_lim = fb_len_max;
|
fb_len_lim, fb_len_max);
|
||||||
|
fb_len_lim = fb_len_max;
|
||||||
}
|
}
|
||||||
if (fb_len_lim && fb_len > fb_len_lim) {
|
if (fb_len_lim && fb_len > fb_len_lim) {
|
||||||
xen_be_printf(&xenfb->c.xendev, 0, "frontend fb size %zu limited to %zu\n",
|
xen_pv_printf(&xenfb->c.xendev, 0,
|
||||||
fb_len, fb_len_lim);
|
"frontend fb size %zu limited to %zu\n",
|
||||||
fb_len = fb_len_lim;
|
fb_len, fb_len_lim);
|
||||||
|
fb_len = fb_len_lim;
|
||||||
}
|
}
|
||||||
if (depth != 8 && depth != 16 && depth != 24 && depth != 32) {
|
if (depth != 8 && depth != 16 && depth != 24 && depth != 32) {
|
||||||
xen_be_printf(&xenfb->c.xendev, 0, "can't handle frontend fb depth %d\n",
|
xen_pv_printf(&xenfb->c.xendev, 0,
|
||||||
depth);
|
"can't handle frontend fb depth %d\n",
|
||||||
return -1;
|
depth);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
if (row_stride <= 0 || row_stride > fb_len) {
|
if (row_stride <= 0 || row_stride > fb_len) {
|
||||||
xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend stride %d\n", row_stride);
|
xen_pv_printf(&xenfb->c.xendev, 0, "invalid frontend stride %d\n",
|
||||||
return -1;
|
row_stride);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
max_width = row_stride / (depth / 8);
|
max_width = row_stride / (depth / 8);
|
||||||
if (width < 0 || width > max_width) {
|
if (width < 0 || width > max_width) {
|
||||||
xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend width %d limited to %d\n",
|
xen_pv_printf(&xenfb->c.xendev, 0,
|
||||||
width, max_width);
|
"invalid frontend width %d limited to %d\n",
|
||||||
width = max_width;
|
width, max_width);
|
||||||
|
width = max_width;
|
||||||
}
|
}
|
||||||
if (offset < 0 || offset >= fb_len) {
|
if (offset < 0 || offset >= fb_len) {
|
||||||
xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend offset %d (max %zu)\n",
|
xen_pv_printf(&xenfb->c.xendev, 0,
|
||||||
offset, fb_len - 1);
|
"invalid frontend offset %d (max %zu)\n",
|
||||||
return -1;
|
offset, fb_len - 1);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
max_height = (fb_len - offset) / row_stride;
|
max_height = (fb_len - offset) / row_stride;
|
||||||
if (height < 0 || height > max_height) {
|
if (height < 0 || height > max_height) {
|
||||||
xen_be_printf(&xenfb->c.xendev, 0, "invalid frontend height %d limited to %d\n",
|
xen_pv_printf(&xenfb->c.xendev, 0,
|
||||||
height, max_height);
|
"invalid frontend height %d limited to %d\n",
|
||||||
height = max_height;
|
height, max_height);
|
||||||
|
height = max_height;
|
||||||
}
|
}
|
||||||
xenfb->fb_len = fb_len;
|
xenfb->fb_len = fb_len;
|
||||||
xenfb->row_stride = row_stride;
|
xenfb->row_stride = row_stride;
|
||||||
|
@ -553,8 +561,9 @@ static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim,
|
||||||
xenfb->offset = offset;
|
xenfb->offset = offset;
|
||||||
xenfb->up_fullscreen = 1;
|
xenfb->up_fullscreen = 1;
|
||||||
xenfb->do_resize = 1;
|
xenfb->do_resize = 1;
|
||||||
xen_be_printf(&xenfb->c.xendev, 1, "framebuffer %dx%dx%d offset %d stride %d\n",
|
xen_pv_printf(&xenfb->c.xendev, 1,
|
||||||
width, height, depth, offset, row_stride);
|
"framebuffer %dx%dx%d offset %d stride %d\n",
|
||||||
|
width, height, depth, offset, row_stride);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,7 +640,7 @@ static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (oops) /* should not happen */
|
if (oops) /* should not happen */
|
||||||
xen_be_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n",
|
xen_pv_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n",
|
||||||
__FUNCTION__, xenfb->depth, bpp);
|
__FUNCTION__, xenfb->depth, bpp);
|
||||||
|
|
||||||
dpy_gfx_update(xenfb->c.con, x, y, w, h);
|
dpy_gfx_update(xenfb->c.con, x, y, w, h);
|
||||||
|
@ -663,7 +672,7 @@ static void xenfb_send_event(struct XenFB *xenfb, union xenfb_in_event *event)
|
||||||
xen_wmb(); /* ensure ring contents visible */
|
xen_wmb(); /* ensure ring contents visible */
|
||||||
page->in_prod = prod + 1;
|
page->in_prod = prod + 1;
|
||||||
|
|
||||||
xen_be_send_notify(&xenfb->c.xendev);
|
xen_pv_send_notify(&xenfb->c.xendev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xenfb_send_refresh_period(struct XenFB *xenfb, int period)
|
static void xenfb_send_refresh_period(struct XenFB *xenfb, int period)
|
||||||
|
@ -696,9 +705,9 @@ static void xenfb_update(void *opaque)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!xenfb->feature_update) {
|
if (!xenfb->feature_update) {
|
||||||
/* we don't get update notifications, thus use the
|
/* we don't get update notifications, thus use the
|
||||||
* sledge hammer approach ... */
|
* sledge hammer approach ... */
|
||||||
xenfb->up_fullscreen = 1;
|
xenfb->up_fullscreen = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* resize if needed */
|
/* resize if needed */
|
||||||
|
@ -721,7 +730,8 @@ static void xenfb_update(void *opaque)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dpy_gfx_replace_surface(xenfb->c.con, surface);
|
dpy_gfx_replace_surface(xenfb->c.con, surface);
|
||||||
xen_be_printf(&xenfb->c.xendev, 1, "update: resizing: %dx%d @ %d bpp%s\n",
|
xen_pv_printf(&xenfb->c.xendev, 1,
|
||||||
|
"update: resizing: %dx%d @ %d bpp%s\n",
|
||||||
xenfb->width, xenfb->height, xenfb->depth,
|
xenfb->width, xenfb->height, xenfb->depth,
|
||||||
is_buffer_shared(surface) ? " (shared)" : "");
|
is_buffer_shared(surface) ? " (shared)" : "");
|
||||||
xenfb->up_fullscreen = 1;
|
xenfb->up_fullscreen = 1;
|
||||||
|
@ -729,18 +739,19 @@ static void xenfb_update(void *opaque)
|
||||||
|
|
||||||
/* run queued updates */
|
/* run queued updates */
|
||||||
if (xenfb->up_fullscreen) {
|
if (xenfb->up_fullscreen) {
|
||||||
xen_be_printf(&xenfb->c.xendev, 3, "update: fullscreen\n");
|
xen_pv_printf(&xenfb->c.xendev, 3, "update: fullscreen\n");
|
||||||
xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
|
xenfb_guest_copy(xenfb, 0, 0, xenfb->width, xenfb->height);
|
||||||
} else if (xenfb->up_count) {
|
} else if (xenfb->up_count) {
|
||||||
xen_be_printf(&xenfb->c.xendev, 3, "update: %d rects\n", xenfb->up_count);
|
xen_pv_printf(&xenfb->c.xendev, 3, "update: %d rects\n",
|
||||||
for (i = 0; i < xenfb->up_count; i++)
|
xenfb->up_count);
|
||||||
xenfb_guest_copy(xenfb,
|
for (i = 0; i < xenfb->up_count; i++)
|
||||||
xenfb->up_rects[i].x,
|
xenfb_guest_copy(xenfb,
|
||||||
xenfb->up_rects[i].y,
|
xenfb->up_rects[i].x,
|
||||||
xenfb->up_rects[i].w,
|
xenfb->up_rects[i].y,
|
||||||
xenfb->up_rects[i].h);
|
xenfb->up_rects[i].w,
|
||||||
|
xenfb->up_rects[i].h);
|
||||||
} else {
|
} else {
|
||||||
xen_be_printf(&xenfb->c.xendev, 3, "update: nothing\n");
|
xen_pv_printf(&xenfb->c.xendev, 3, "update: nothing\n");
|
||||||
}
|
}
|
||||||
xenfb->up_count = 0;
|
xenfb->up_count = 0;
|
||||||
xenfb->up_fullscreen = 0;
|
xenfb->up_fullscreen = 0;
|
||||||
|
@ -794,14 +805,14 @@ static void xenfb_handle_events(struct XenFB *xenfb)
|
||||||
w = MIN(event->update.width, xenfb->width - x);
|
w = MIN(event->update.width, xenfb->width - x);
|
||||||
h = MIN(event->update.height, xenfb->height - y);
|
h = MIN(event->update.height, xenfb->height - y);
|
||||||
if (w < 0 || h < 0) {
|
if (w < 0 || h < 0) {
|
||||||
xen_be_printf(&xenfb->c.xendev, 1, "bogus update ignored\n");
|
xen_pv_printf(&xenfb->c.xendev, 1, "bogus update ignored\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (x != event->update.x ||
|
if (x != event->update.x ||
|
||||||
y != event->update.y ||
|
y != event->update.y ||
|
||||||
w != event->update.width ||
|
w != event->update.width ||
|
||||||
h != event->update.height) {
|
h != event->update.height) {
|
||||||
xen_be_printf(&xenfb->c.xendev, 1, "bogus update clipped\n");
|
xen_pv_printf(&xenfb->c.xendev, 1, "bogus update clipped\n");
|
||||||
}
|
}
|
||||||
if (w == xenfb->width && h > xenfb->height / 2) {
|
if (w == xenfb->width && h > xenfb->height / 2) {
|
||||||
/* scroll detector: updated more than 50% of the lines,
|
/* scroll detector: updated more than 50% of the lines,
|
||||||
|
@ -883,7 +894,7 @@ static int fb_initialise(struct XenDevice *xendev)
|
||||||
if (fb->feature_update)
|
if (fb->feature_update)
|
||||||
xenstore_write_be_int(xendev, "request-update", 1);
|
xenstore_write_be_int(xendev, "request-update", 1);
|
||||||
|
|
||||||
xen_be_printf(xendev, 1, "feature-update=%d, videoram=%d\n",
|
xen_pv_printf(xendev, 1, "feature-update=%d, videoram=%d\n",
|
||||||
fb->feature_update, videoram);
|
fb->feature_update, videoram);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -902,7 +913,7 @@ static void fb_disconnect(struct XenDevice *xendev)
|
||||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON,
|
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON,
|
||||||
-1, 0);
|
-1, 0);
|
||||||
if (fb->pixels == MAP_FAILED) {
|
if (fb->pixels == MAP_FAILED) {
|
||||||
xen_be_printf(xendev, 0,
|
xen_pv_printf(xendev, 0,
|
||||||
"Couldn't replace the framebuffer with anonymous memory errno=%d\n",
|
"Couldn't replace the framebuffer with anonymous memory errno=%d\n",
|
||||||
errno);
|
errno);
|
||||||
}
|
}
|
||||||
|
@ -923,7 +934,7 @@ static void fb_frontend_changed(struct XenDevice *xendev, const char *node)
|
||||||
if (fb->bug_trigger == 0 && strcmp(node, "state") == 0 &&
|
if (fb->bug_trigger == 0 && strcmp(node, "state") == 0 &&
|
||||||
xendev->fe_state == XenbusStateConnected &&
|
xendev->fe_state == XenbusStateConnected &&
|
||||||
xendev->be_state == XenbusStateConnected) {
|
xendev->be_state == XenbusStateConnected) {
|
||||||
xen_be_printf(xendev, 2, "re-trigger connected (frontend bug)\n");
|
xen_pv_printf(xendev, 2, "re-trigger connected (frontend bug)\n");
|
||||||
xen_be_set_state(xendev, XenbusStateConnected);
|
xen_be_set_state(xendev, XenbusStateConnected);
|
||||||
fb->bug_trigger = 1; /* only once */
|
fb->bug_trigger = 1; /* only once */
|
||||||
}
|
}
|
||||||
|
@ -934,7 +945,7 @@ static void fb_event(struct XenDevice *xendev)
|
||||||
struct XenFB *xenfb = container_of(xendev, struct XenFB, c.xendev);
|
struct XenFB *xenfb = container_of(xendev, struct XenFB, c.xendev);
|
||||||
|
|
||||||
xenfb_handle_events(xenfb);
|
xenfb_handle_events(xenfb);
|
||||||
xen_be_send_notify(&xenfb->c.xendev);
|
xen_pv_send_notify(&xenfb->c.xendev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -977,14 +988,14 @@ void xen_init_display(int domid)
|
||||||
wait_more:
|
wait_more:
|
||||||
i++;
|
i++;
|
||||||
main_loop_wait(true);
|
main_loop_wait(true);
|
||||||
xfb = xen_be_find_xendev("vfb", domid, 0);
|
xfb = xen_pv_find_xendev("vfb", domid, 0);
|
||||||
xin = xen_be_find_xendev("vkbd", domid, 0);
|
xin = xen_pv_find_xendev("vkbd", domid, 0);
|
||||||
if (!xfb || !xin) {
|
if (!xfb || !xin) {
|
||||||
if (i < 256) {
|
if (i < 256) {
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
goto wait_more;
|
goto wait_more;
|
||||||
}
|
}
|
||||||
xen_be_printf(NULL, 1, "displaystate setup failed\n");
|
xen_pv_printf(NULL, 1, "displaystate setup failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ static void net_tx_response(struct XenNetDev *netdev, netif_tx_request_t *txp, i
|
||||||
netdev->tx_ring.rsp_prod_pvt = ++i;
|
netdev->tx_ring.rsp_prod_pvt = ++i;
|
||||||
RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->tx_ring, notify);
|
RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->tx_ring, notify);
|
||||||
if (notify) {
|
if (notify) {
|
||||||
xen_be_send_notify(&netdev->xendev);
|
xen_pv_send_notify(&netdev->xendev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == netdev->tx_ring.req_cons) {
|
if (i == netdev->tx_ring.req_cons) {
|
||||||
|
@ -128,30 +128,32 @@ static void net_tx_packets(struct XenNetDev *netdev)
|
||||||
/* should not happen in theory, we don't announce the *
|
/* should not happen in theory, we don't announce the *
|
||||||
* feature-{sg,gso,whatelse} flags in xenstore (yet?) */
|
* feature-{sg,gso,whatelse} flags in xenstore (yet?) */
|
||||||
if (txreq.flags & NETTXF_extra_info) {
|
if (txreq.flags & NETTXF_extra_info) {
|
||||||
xen_be_printf(&netdev->xendev, 0, "FIXME: extra info flag\n");
|
xen_pv_printf(&netdev->xendev, 0, "FIXME: extra info flag\n");
|
||||||
net_tx_error(netdev, &txreq, rc);
|
net_tx_error(netdev, &txreq, rc);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (txreq.flags & NETTXF_more_data) {
|
if (txreq.flags & NETTXF_more_data) {
|
||||||
xen_be_printf(&netdev->xendev, 0, "FIXME: more data flag\n");
|
xen_pv_printf(&netdev->xendev, 0, "FIXME: more data flag\n");
|
||||||
net_tx_error(netdev, &txreq, rc);
|
net_tx_error(netdev, &txreq, rc);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (txreq.size < 14) {
|
if (txreq.size < 14) {
|
||||||
xen_be_printf(&netdev->xendev, 0, "bad packet size: %d\n", txreq.size);
|
xen_pv_printf(&netdev->xendev, 0, "bad packet size: %d\n",
|
||||||
|
txreq.size);
|
||||||
net_tx_error(netdev, &txreq, rc);
|
net_tx_error(netdev, &txreq, rc);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((txreq.offset + txreq.size) > XC_PAGE_SIZE) {
|
if ((txreq.offset + txreq.size) > XC_PAGE_SIZE) {
|
||||||
xen_be_printf(&netdev->xendev, 0, "error: page crossing\n");
|
xen_pv_printf(&netdev->xendev, 0, "error: page crossing\n");
|
||||||
net_tx_error(netdev, &txreq, rc);
|
net_tx_error(netdev, &txreq, rc);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
xen_be_printf(&netdev->xendev, 3, "tx packet ref %d, off %d, len %d, flags 0x%x%s%s%s%s\n",
|
xen_pv_printf(&netdev->xendev, 3,
|
||||||
|
"tx packet ref %d, off %d, len %d, flags 0x%x%s%s%s%s\n",
|
||||||
txreq.gref, txreq.offset, txreq.size, txreq.flags,
|
txreq.gref, txreq.offset, txreq.size, txreq.flags,
|
||||||
(txreq.flags & NETTXF_csum_blank) ? " csum_blank" : "",
|
(txreq.flags & NETTXF_csum_blank) ? " csum_blank" : "",
|
||||||
(txreq.flags & NETTXF_data_validated) ? " data_validated" : "",
|
(txreq.flags & NETTXF_data_validated) ? " data_validated" : "",
|
||||||
|
@ -162,8 +164,9 @@ static void net_tx_packets(struct XenNetDev *netdev)
|
||||||
netdev->xendev.dom,
|
netdev->xendev.dom,
|
||||||
txreq.gref, PROT_READ);
|
txreq.gref, PROT_READ);
|
||||||
if (page == NULL) {
|
if (page == NULL) {
|
||||||
xen_be_printf(&netdev->xendev, 0, "error: tx gref dereference failed (%d)\n",
|
xen_pv_printf(&netdev->xendev, 0,
|
||||||
txreq.gref);
|
"error: tx gref dereference failed (%d)\n",
|
||||||
|
txreq.gref);
|
||||||
net_tx_error(netdev, &txreq, rc);
|
net_tx_error(netdev, &txreq, rc);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -211,13 +214,14 @@ static void net_rx_response(struct XenNetDev *netdev,
|
||||||
resp->status = (int16_t)st;
|
resp->status = (int16_t)st;
|
||||||
}
|
}
|
||||||
|
|
||||||
xen_be_printf(&netdev->xendev, 3, "rx response: idx %d, status %d, flags 0x%x\n",
|
xen_pv_printf(&netdev->xendev, 3,
|
||||||
|
"rx response: idx %d, status %d, flags 0x%x\n",
|
||||||
i, resp->status, resp->flags);
|
i, resp->status, resp->flags);
|
||||||
|
|
||||||
netdev->rx_ring.rsp_prod_pvt = ++i;
|
netdev->rx_ring.rsp_prod_pvt = ++i;
|
||||||
RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->rx_ring, notify);
|
RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->rx_ring, notify);
|
||||||
if (notify) {
|
if (notify) {
|
||||||
xen_be_send_notify(&netdev->xendev);
|
xen_pv_send_notify(&netdev->xendev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +246,7 @@ static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {
|
if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {
|
||||||
xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
|
xen_pv_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
|
||||||
(unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
|
(unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -254,7 +258,8 @@ static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size
|
||||||
netdev->xendev.dom,
|
netdev->xendev.dom,
|
||||||
rxreq.gref, PROT_WRITE);
|
rxreq.gref, PROT_WRITE);
|
||||||
if (page == NULL) {
|
if (page == NULL) {
|
||||||
xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n",
|
xen_pv_printf(&netdev->xendev, 0,
|
||||||
|
"error: rx gref dereference failed (%d)\n",
|
||||||
rxreq.gref);
|
rxreq.gref);
|
||||||
net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
|
net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -328,7 +333,8 @@ static int net_connect(struct XenDevice *xendev)
|
||||||
rx_copy = 0;
|
rx_copy = 0;
|
||||||
}
|
}
|
||||||
if (rx_copy == 0) {
|
if (rx_copy == 0) {
|
||||||
xen_be_printf(&netdev->xendev, 0, "frontend doesn't support rx-copy.\n");
|
xen_pv_printf(&netdev->xendev, 0,
|
||||||
|
"frontend doesn't support rx-copy.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,7 +359,7 @@ static int net_connect(struct XenDevice *xendev)
|
||||||
|
|
||||||
xen_be_bind_evtchn(&netdev->xendev);
|
xen_be_bind_evtchn(&netdev->xendev);
|
||||||
|
|
||||||
xen_be_printf(&netdev->xendev, 1, "ok: tx-ring-ref %d, rx-ring-ref %d, "
|
xen_pv_printf(&netdev->xendev, 1, "ok: tx-ring-ref %d, rx-ring-ref %d, "
|
||||||
"remote port %d, local port %d\n",
|
"remote port %d, local port %d\n",
|
||||||
netdev->tx_ring_ref, netdev->rx_ring_ref,
|
netdev->tx_ring_ref, netdev->rx_ring_ref,
|
||||||
netdev->xendev.remote_port, netdev->xendev.local_port);
|
netdev->xendev.remote_port, netdev->xendev.local_port);
|
||||||
|
@ -366,7 +372,7 @@ static void net_disconnect(struct XenDevice *xendev)
|
||||||
{
|
{
|
||||||
struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
|
struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
|
||||||
|
|
||||||
xen_be_unbind_evtchn(&netdev->xendev);
|
xen_pv_unbind_evtchn(&netdev->xendev);
|
||||||
|
|
||||||
if (netdev->txs) {
|
if (netdev->txs) {
|
||||||
xengnttab_unmap(netdev->xendev.gnttabdev, netdev->txs, 1);
|
xengnttab_unmap(netdev->xendev.gnttabdev, netdev->txs, 1);
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
struct timeval tv; \
|
struct timeval tv; \
|
||||||
\
|
\
|
||||||
gettimeofday(&tv, NULL); \
|
gettimeofday(&tv, NULL); \
|
||||||
xen_be_printf(xendev, lvl, "%8ld.%06ld xen-usb(%s):" fmt, \
|
xen_pv_printf(xendev, lvl, "%8ld.%06ld xen-usb(%s):" fmt, \
|
||||||
tv.tv_sec, tv.tv_usec, __func__, ##args); \
|
tv.tv_sec, tv.tv_usec, __func__, ##args); \
|
||||||
}
|
}
|
||||||
#define TR_BUS(xendev, fmt, args...) TR(xendev, 2, fmt, ##args)
|
#define TR_BUS(xendev, fmt, args...) TR(xendev, 2, fmt, ##args)
|
||||||
|
@ -153,7 +153,7 @@ static int usbback_gnttab_map(struct usbback_req *usbback_req)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nr_segs > USBIF_MAX_SEGMENTS_PER_REQUEST) {
|
if (nr_segs > USBIF_MAX_SEGMENTS_PER_REQUEST) {
|
||||||
xen_be_printf(xendev, 0, "bad number of segments in request (%d)\n",
|
xen_pv_printf(xendev, 0, "bad number of segments in request (%d)\n",
|
||||||
nr_segs);
|
nr_segs);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@ static int usbback_gnttab_map(struct usbback_req *usbback_req)
|
||||||
for (i = 0; i < nr_segs; i++) {
|
for (i = 0; i < nr_segs; i++) {
|
||||||
if ((unsigned)usbback_req->req.seg[i].offset +
|
if ((unsigned)usbback_req->req.seg[i].offset +
|
||||||
(unsigned)usbback_req->req.seg[i].length > XC_PAGE_SIZE) {
|
(unsigned)usbback_req->req.seg[i].length > XC_PAGE_SIZE) {
|
||||||
xen_be_printf(xendev, 0, "segment crosses page boundary\n");
|
xen_pv_printf(xendev, 0, "segment crosses page boundary\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ static int usbback_gnttab_map(struct usbback_req *usbback_req)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!usbback_req->nr_extra_segs) {
|
if (!usbback_req->nr_extra_segs) {
|
||||||
xen_be_printf(xendev, 0, "iso request without descriptor segments\n");
|
xen_pv_printf(xendev, 0, "iso request without descriptor segments\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +314,7 @@ static void usbback_do_response(struct usbback_req *usbback_req, int32_t status,
|
||||||
RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&usbif->urb_ring, notify);
|
RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&usbif->urb_ring, notify);
|
||||||
|
|
||||||
if (notify) {
|
if (notify) {
|
||||||
xen_be_send_notify(xendev);
|
xen_pv_send_notify(xendev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,14 +551,14 @@ static void usbback_dispatch(struct usbback_req *usbback_req)
|
||||||
|
|
||||||
ret = usbback_init_packet(usbback_req);
|
ret = usbback_init_packet(usbback_req);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
xen_be_printf(&usbif->xendev, 0, "invalid request\n");
|
xen_pv_printf(&usbif->xendev, 0, "invalid request\n");
|
||||||
ret = -ESHUTDOWN;
|
ret = -ESHUTDOWN;
|
||||||
goto fail_free_urb;
|
goto fail_free_urb;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = usbback_gnttab_map(usbback_req);
|
ret = usbback_gnttab_map(usbback_req);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
xen_be_printf(&usbif->xendev, 0, "invalid buffer, ret=%d\n", ret);
|
xen_pv_printf(&usbif->xendev, 0, "invalid buffer, ret=%d\n", ret);
|
||||||
ret = -ESHUTDOWN;
|
ret = -ESHUTDOWN;
|
||||||
goto fail_free_urb;
|
goto fail_free_urb;
|
||||||
}
|
}
|
||||||
|
@ -590,7 +590,7 @@ static void usbback_hotplug_notify(struct usbback_info *usbif)
|
||||||
|
|
||||||
/* Check for full ring. */
|
/* Check for full ring. */
|
||||||
if ((RING_SIZE(ring) - ring->rsp_prod_pvt - ring->req_cons) == 0) {
|
if ((RING_SIZE(ring) - ring->rsp_prod_pvt - ring->req_cons) == 0) {
|
||||||
xen_be_send_notify(&usbif->xendev);
|
xen_pv_send_notify(&usbif->xendev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,7 +609,7 @@ static void usbback_hotplug_notify(struct usbback_info *usbif)
|
||||||
RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(ring, notify);
|
RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(ring, notify);
|
||||||
|
|
||||||
if (notify) {
|
if (notify) {
|
||||||
xen_be_send_notify(&usbif->xendev);
|
xen_pv_send_notify(&usbif->xendev);
|
||||||
}
|
}
|
||||||
|
|
||||||
TR_BUS(&usbif->xendev, "hotplug port %d speed %d\n", usb_hp->port,
|
TR_BUS(&usbif->xendev, "hotplug port %d speed %d\n", usb_hp->port,
|
||||||
|
@ -646,7 +646,7 @@ static void usbback_bh(void *opaque)
|
||||||
|
|
||||||
if (RING_REQUEST_PROD_OVERFLOW(urb_ring, rp)) {
|
if (RING_REQUEST_PROD_OVERFLOW(urb_ring, rp)) {
|
||||||
rc = urb_ring->rsp_prod_pvt;
|
rc = urb_ring->rsp_prod_pvt;
|
||||||
xen_be_printf(&usbif->xendev, 0, "domU provided bogus ring requests "
|
xen_pv_printf(&usbif->xendev, 0, "domU provided bogus ring requests "
|
||||||
"(%#x - %#x = %u). Halting ring processing.\n",
|
"(%#x - %#x = %u). Halting ring processing.\n",
|
||||||
rp, rc, rp - rc);
|
rp, rc, rp - rc);
|
||||||
usbif->ring_error = true;
|
usbif->ring_error = true;
|
||||||
|
@ -744,7 +744,7 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
|
||||||
|
|
||||||
portname = strchr(busid, '-');
|
portname = strchr(busid, '-');
|
||||||
if (!portname) {
|
if (!portname) {
|
||||||
xen_be_printf(&usbif->xendev, 0, "device %s illegal specification\n",
|
xen_pv_printf(&usbif->xendev, 0, "device %s illegal specification\n",
|
||||||
busid);
|
busid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -783,7 +783,7 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (speed == USBIF_SPEED_NONE) {
|
if (speed == USBIF_SPEED_NONE) {
|
||||||
xen_be_printf(&usbif->xendev, 0, "device %s wrong speed\n", busid);
|
xen_pv_printf(&usbif->xendev, 0, "device %s wrong speed\n", busid);
|
||||||
object_unparent(OBJECT(usbif->ports[port - 1].dev));
|
object_unparent(OBJECT(usbif->ports[port - 1].dev));
|
||||||
usbif->ports[port - 1].dev = NULL;
|
usbif->ports[port - 1].dev = NULL;
|
||||||
return;
|
return;
|
||||||
|
@ -800,7 +800,7 @@ static void usbback_portid_add(struct usbback_info *usbif, unsigned port,
|
||||||
err:
|
err:
|
||||||
QDECREF(qdict);
|
QDECREF(qdict);
|
||||||
snprintf(p->path, sizeof(p->path), "%d", 99);
|
snprintf(p->path, sizeof(p->path), "%d", 99);
|
||||||
xen_be_printf(&usbif->xendev, 0, "device %s could not be opened\n", busid);
|
xen_pv_printf(&usbif->xendev, 0, "device %s could not be opened\n", busid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usbback_process_port(struct usbback_info *usbif, unsigned port)
|
static void usbback_process_port(struct usbback_info *usbif, unsigned port)
|
||||||
|
@ -811,7 +811,7 @@ static void usbback_process_port(struct usbback_info *usbif, unsigned port)
|
||||||
snprintf(node, sizeof(node), "port/%d", port);
|
snprintf(node, sizeof(node), "port/%d", port);
|
||||||
busid = xenstore_read_be_str(&usbif->xendev, node);
|
busid = xenstore_read_be_str(&usbif->xendev, node);
|
||||||
if (busid == NULL) {
|
if (busid == NULL) {
|
||||||
xen_be_printf(&usbif->xendev, 0, "xenstore_read %s failed\n", node);
|
xen_pv_printf(&usbif->xendev, 0, "xenstore_read %s failed\n", node);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,7 +834,7 @@ static void usbback_disconnect(struct XenDevice *xendev)
|
||||||
|
|
||||||
usbif = container_of(xendev, struct usbback_info, xendev);
|
usbif = container_of(xendev, struct usbback_info, xendev);
|
||||||
|
|
||||||
xen_be_unbind_evtchn(xendev);
|
xen_pv_unbind_evtchn(xendev);
|
||||||
|
|
||||||
if (usbif->urb_sring) {
|
if (usbif->urb_sring) {
|
||||||
xengnttab_unmap(xendev->gnttabdev, usbif->urb_sring, 1);
|
xengnttab_unmap(xendev->gnttabdev, usbif->urb_sring, 1);
|
||||||
|
@ -868,15 +868,15 @@ static int usbback_connect(struct XenDevice *xendev)
|
||||||
usbif = container_of(xendev, struct usbback_info, xendev);
|
usbif = container_of(xendev, struct usbback_info, xendev);
|
||||||
|
|
||||||
if (xenstore_read_fe_int(xendev, "urb-ring-ref", &urb_ring_ref)) {
|
if (xenstore_read_fe_int(xendev, "urb-ring-ref", &urb_ring_ref)) {
|
||||||
xen_be_printf(xendev, 0, "error reading urb-ring-ref\n");
|
xen_pv_printf(xendev, 0, "error reading urb-ring-ref\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (xenstore_read_fe_int(xendev, "conn-ring-ref", &conn_ring_ref)) {
|
if (xenstore_read_fe_int(xendev, "conn-ring-ref", &conn_ring_ref)) {
|
||||||
xen_be_printf(xendev, 0, "error reading conn-ring-ref\n");
|
xen_pv_printf(xendev, 0, "error reading conn-ring-ref\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (xenstore_read_fe_int(xendev, "event-channel", &xendev->remote_port)) {
|
if (xenstore_read_fe_int(xendev, "event-channel", &xendev->remote_port)) {
|
||||||
xen_be_printf(xendev, 0, "error reading event-channel\n");
|
xen_pv_printf(xendev, 0, "error reading event-channel\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -887,7 +887,7 @@ static int usbback_connect(struct XenDevice *xendev)
|
||||||
conn_ring_ref,
|
conn_ring_ref,
|
||||||
PROT_READ | PROT_WRITE);
|
PROT_READ | PROT_WRITE);
|
||||||
if (!usbif->urb_sring || !usbif->conn_sring) {
|
if (!usbif->urb_sring || !usbif->conn_sring) {
|
||||||
xen_be_printf(xendev, 0, "error mapping rings\n");
|
xen_pv_printf(xendev, 0, "error mapping rings\n");
|
||||||
usbback_disconnect(xendev);
|
usbback_disconnect(xendev);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -899,7 +899,7 @@ static int usbback_connect(struct XenDevice *xendev)
|
||||||
|
|
||||||
xen_be_bind_evtchn(xendev);
|
xen_be_bind_evtchn(xendev);
|
||||||
|
|
||||||
xen_be_printf(xendev, 1, "urb-ring-ref %d, conn-ring-ref %d, "
|
xen_pv_printf(xendev, 1, "urb-ring-ref %d, conn-ring-ref %d, "
|
||||||
"remote port %d, local port %d\n", urb_ring_ref,
|
"remote port %d, local port %d\n", urb_ring_ref,
|
||||||
conn_ring_ref, xendev->remote_port, xendev->local_port);
|
conn_ring_ref, xendev->remote_port, xendev->local_port);
|
||||||
|
|
||||||
|
@ -935,12 +935,12 @@ static int usbback_init(struct XenDevice *xendev)
|
||||||
|
|
||||||
if (xenstore_read_be_int(xendev, "num-ports", &usbif->num_ports) ||
|
if (xenstore_read_be_int(xendev, "num-ports", &usbif->num_ports) ||
|
||||||
usbif->num_ports < 1 || usbif->num_ports > USBBACK_MAXPORTS) {
|
usbif->num_ports < 1 || usbif->num_ports > USBBACK_MAXPORTS) {
|
||||||
xen_be_printf(xendev, 0, "num-ports not readable or out of bounds\n");
|
xen_pv_printf(xendev, 0, "num-ports not readable or out of bounds\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (xenstore_read_be_int(xendev, "usb-ver", &usbif->usb_ver) ||
|
if (xenstore_read_be_int(xendev, "usb-ver", &usbif->usb_ver) ||
|
||||||
(usbif->usb_ver != USB_VER_USB11 && usbif->usb_ver != USB_VER_USB20)) {
|
(usbif->usb_ver != USB_VER_USB11 && usbif->usb_ver != USB_VER_USB20)) {
|
||||||
xen_be_printf(xendev, 0, "usb-ver not readable or out of bounds\n");
|
xen_pv_printf(xendev, 0, "usb-ver not readable or out of bounds\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1028,7 +1028,7 @@ static void usbback_alloc(struct XenDevice *xendev)
|
||||||
/* max_grants: for each request and for the rings (request and connect). */
|
/* max_grants: for each request and for the rings (request and connect). */
|
||||||
max_grants = USBIF_MAX_SEGMENTS_PER_REQUEST * USB_URB_RING_SIZE + 2;
|
max_grants = USBIF_MAX_SEGMENTS_PER_REQUEST * USB_URB_RING_SIZE + 2;
|
||||||
if (xengnttab_set_max_grants(xendev->gnttabdev, max_grants) < 0) {
|
if (xengnttab_set_max_grants(xendev->gnttabdev, max_grants) < 0) {
|
||||||
xen_be_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n",
|
xen_pv_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# xen backend driver support
|
# xen backend driver support
|
||||||
common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o
|
common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o xen_pvdev.o
|
||||||
|
|
||||||
obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
|
obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
|
||||||
obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o
|
obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "sysemu/char.h"
|
#include "sysemu/char.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
#include "hw/xen/xen_backend.h"
|
#include "hw/xen/xen_backend.h"
|
||||||
|
#include "hw/xen/xen_pvdev.h"
|
||||||
|
|
||||||
#include <xen/grant_table.h>
|
#include <xen/grant_table.h>
|
||||||
|
|
||||||
|
@ -46,129 +47,7 @@ struct xs_handle *xenstore = NULL;
|
||||||
const char *xen_protocol;
|
const char *xen_protocol;
|
||||||
|
|
||||||
/* private */
|
/* private */
|
||||||
struct xs_dirs {
|
static int debug;
|
||||||
char *xs_dir;
|
|
||||||
QTAILQ_ENTRY(xs_dirs) list;
|
|
||||||
};
|
|
||||||
static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup =
|
|
||||||
QTAILQ_HEAD_INITIALIZER(xs_cleanup);
|
|
||||||
|
|
||||||
static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = QTAILQ_HEAD_INITIALIZER(xendevs);
|
|
||||||
static int debug = 0;
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
|
|
||||||
static void xenstore_cleanup_dir(char *dir)
|
|
||||||
{
|
|
||||||
struct xs_dirs *d;
|
|
||||||
|
|
||||||
d = g_malloc(sizeof(*d));
|
|
||||||
d->xs_dir = dir;
|
|
||||||
QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
void xen_config_cleanup(void)
|
|
||||||
{
|
|
||||||
struct xs_dirs *d;
|
|
||||||
|
|
||||||
QTAILQ_FOREACH(d, &xs_cleanup, list) {
|
|
||||||
xs_rm(xenstore, 0, d->xs_dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int xenstore_write_str(const char *base, const char *node, const char *val)
|
|
||||||
{
|
|
||||||
char abspath[XEN_BUFSIZE];
|
|
||||||
|
|
||||||
snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
|
|
||||||
if (!xs_write(xenstore, 0, abspath, val, strlen(val))) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *xenstore_read_str(const char *base, const char *node)
|
|
||||||
{
|
|
||||||
char abspath[XEN_BUFSIZE];
|
|
||||||
unsigned int len;
|
|
||||||
char *str, *ret = NULL;
|
|
||||||
|
|
||||||
snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
|
|
||||||
str = xs_read(xenstore, 0, abspath, &len);
|
|
||||||
if (str != NULL) {
|
|
||||||
/* move to qemu-allocated memory to make sure
|
|
||||||
* callers can savely g_free() stuff. */
|
|
||||||
ret = g_strdup(str);
|
|
||||||
free(str);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xenstore_mkdir(char *path, int p)
|
|
||||||
{
|
|
||||||
struct xs_permissions perms[2] = {
|
|
||||||
{
|
|
||||||
.id = 0, /* set owner: dom0 */
|
|
||||||
}, {
|
|
||||||
.id = xen_domid,
|
|
||||||
.perms = p,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!xs_mkdir(xenstore, 0, path)) {
|
|
||||||
xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
xenstore_cleanup_dir(g_strdup(path));
|
|
||||||
|
|
||||||
if (!xs_set_permissions(xenstore, 0, path, perms, 2)) {
|
|
||||||
xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xenstore_write_int(const char *base, const char *node, int ival)
|
|
||||||
{
|
|
||||||
char val[12];
|
|
||||||
|
|
||||||
snprintf(val, sizeof(val), "%d", ival);
|
|
||||||
return xenstore_write_str(base, node, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
int xenstore_write_int64(const char *base, const char *node, int64_t ival)
|
|
||||||
{
|
|
||||||
char val[21];
|
|
||||||
|
|
||||||
snprintf(val, sizeof(val), "%"PRId64, ival);
|
|
||||||
return xenstore_write_str(base, node, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
int xenstore_read_int(const char *base, const char *node, int *ival)
|
|
||||||
{
|
|
||||||
char *val;
|
|
||||||
int rc = -1;
|
|
||||||
|
|
||||||
val = xenstore_read_str(base, node);
|
|
||||||
if (val && 1 == sscanf(val, "%d", ival)) {
|
|
||||||
rc = 0;
|
|
||||||
}
|
|
||||||
g_free(val);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xenstore_read_uint64(const char *base, const char *node, uint64_t *uval)
|
|
||||||
{
|
|
||||||
char *val;
|
|
||||||
int rc = -1;
|
|
||||||
|
|
||||||
val = xenstore_read_str(base, node);
|
|
||||||
if (val && 1 == sscanf(val, "%"SCNu64, uval)) {
|
|
||||||
rc = 0;
|
|
||||||
}
|
|
||||||
g_free(val);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val)
|
int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val)
|
||||||
{
|
{
|
||||||
|
@ -205,27 +84,14 @@ int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival)
|
||||||
return xenstore_read_int(xendev->fe, node, ival);
|
return xenstore_read_int(xendev->fe, node, ival);
|
||||||
}
|
}
|
||||||
|
|
||||||
int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node, uint64_t *uval)
|
int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node,
|
||||||
|
uint64_t *uval)
|
||||||
{
|
{
|
||||||
return xenstore_read_uint64(xendev->fe, node, uval);
|
return xenstore_read_uint64(xendev->fe, node, uval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
|
||||||
const char *xenbus_strstate(enum xenbus_state state)
|
|
||||||
{
|
|
||||||
static const char *const name[] = {
|
|
||||||
[ XenbusStateUnknown ] = "Unknown",
|
|
||||||
[ XenbusStateInitialising ] = "Initialising",
|
|
||||||
[ XenbusStateInitWait ] = "InitWait",
|
|
||||||
[ XenbusStateInitialised ] = "Initialised",
|
|
||||||
[ XenbusStateConnected ] = "Connected",
|
|
||||||
[ XenbusStateClosing ] = "Closing",
|
|
||||||
[ XenbusStateClosed ] = "Closed",
|
|
||||||
};
|
|
||||||
return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
|
|
||||||
}
|
|
||||||
|
|
||||||
int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
|
int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -234,33 +100,12 @@ int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
xen_be_printf(xendev, 1, "backend state: %s -> %s\n",
|
xen_pv_printf(xendev, 1, "backend state: %s -> %s\n",
|
||||||
xenbus_strstate(xendev->be_state), xenbus_strstate(state));
|
xenbus_strstate(xendev->be_state), xenbus_strstate(state));
|
||||||
xendev->be_state = state;
|
xendev->be_state = state;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
|
|
||||||
struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev)
|
|
||||||
{
|
|
||||||
struct XenDevice *xendev;
|
|
||||||
|
|
||||||
QTAILQ_FOREACH(xendev, &xendevs, next) {
|
|
||||||
if (xendev->dom != dom) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (xendev->dev != dev) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (strcmp(xendev->type, type) != 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return xendev;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get xen backend device, allocate a new one if it doesn't exist.
|
* get xen backend device, allocate a new one if it doesn't exist.
|
||||||
*/
|
*/
|
||||||
|
@ -269,7 +114,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
|
||||||
{
|
{
|
||||||
struct XenDevice *xendev;
|
struct XenDevice *xendev;
|
||||||
|
|
||||||
xendev = xen_be_find_xendev(type, dom, dev);
|
xendev = xen_pv_find_xendev(type, dom, dev);
|
||||||
if (xendev) {
|
if (xendev) {
|
||||||
return xendev;
|
return xendev;
|
||||||
}
|
}
|
||||||
|
@ -291,7 +136,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
|
||||||
|
|
||||||
xendev->evtchndev = xenevtchn_open(NULL, 0);
|
xendev->evtchndev = xenevtchn_open(NULL, 0);
|
||||||
if (xendev->evtchndev == NULL) {
|
if (xendev->evtchndev == NULL) {
|
||||||
xen_be_printf(NULL, 0, "can't open evtchn device\n");
|
xen_pv_printf(NULL, 0, "can't open evtchn device\n");
|
||||||
g_free(xendev);
|
g_free(xendev);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -300,7 +145,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
|
||||||
if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
|
if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
|
||||||
xendev->gnttabdev = xengnttab_open(NULL, 0);
|
xendev->gnttabdev = xengnttab_open(NULL, 0);
|
||||||
if (xendev->gnttabdev == NULL) {
|
if (xendev->gnttabdev == NULL) {
|
||||||
xen_be_printf(NULL, 0, "can't open gnttab device\n");
|
xen_pv_printf(NULL, 0, "can't open gnttab device\n");
|
||||||
xenevtchn_close(xendev->evtchndev);
|
xenevtchn_close(xendev->evtchndev);
|
||||||
g_free(xendev);
|
g_free(xendev);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -309,7 +154,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
|
||||||
xendev->gnttabdev = NULL;
|
xendev->gnttabdev = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTAILQ_INSERT_TAIL(&xendevs, xendev, next);
|
xen_pv_insert_xendev(xendev);
|
||||||
|
|
||||||
if (xendev->ops->alloc) {
|
if (xendev->ops->alloc) {
|
||||||
xendev->ops->alloc(xendev);
|
xendev->ops->alloc(xendev);
|
||||||
|
@ -318,32 +163,6 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
|
||||||
return xendev;
|
return xendev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* release xen backend device.
|
|
||||||
*/
|
|
||||||
static void xen_be_del_xendev(struct XenDevice *xendev)
|
|
||||||
{
|
|
||||||
if (xendev->ops->free) {
|
|
||||||
xendev->ops->free(xendev);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xendev->fe) {
|
|
||||||
char token[XEN_BUFSIZE];
|
|
||||||
snprintf(token, sizeof(token), "fe:%p", xendev);
|
|
||||||
xs_unwatch(xenstore, xendev->fe, token);
|
|
||||||
g_free(xendev->fe);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xendev->evtchndev != NULL) {
|
|
||||||
xenevtchn_close(xendev->evtchndev);
|
|
||||||
}
|
|
||||||
if (xendev->gnttabdev != NULL) {
|
|
||||||
xengnttab_close(xendev->gnttabdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
QTAILQ_REMOVE(&xendevs, xendev, next);
|
|
||||||
g_free(xendev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sync internal data structures on xenstore updates.
|
* Sync internal data structures on xenstore updates.
|
||||||
|
@ -359,7 +178,7 @@ static void xen_be_backend_changed(struct XenDevice *xendev, const char *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
xen_be_printf(xendev, 2, "backend update: %s\n", node);
|
xen_pv_printf(xendev, 2, "backend update: %s\n", node);
|
||||||
if (xendev->ops->backend_changed) {
|
if (xendev->ops->backend_changed) {
|
||||||
xendev->ops->backend_changed(xendev, node);
|
xendev->ops->backend_changed(xendev, node);
|
||||||
}
|
}
|
||||||
|
@ -375,7 +194,7 @@ static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
|
||||||
fe_state = XenbusStateUnknown;
|
fe_state = XenbusStateUnknown;
|
||||||
}
|
}
|
||||||
if (xendev->fe_state != fe_state) {
|
if (xendev->fe_state != fe_state) {
|
||||||
xen_be_printf(xendev, 1, "frontend state: %s -> %s\n",
|
xen_pv_printf(xendev, 1, "frontend state: %s -> %s\n",
|
||||||
xenbus_strstate(xendev->fe_state),
|
xenbus_strstate(xendev->fe_state),
|
||||||
xenbus_strstate(fe_state));
|
xenbus_strstate(fe_state));
|
||||||
}
|
}
|
||||||
|
@ -385,12 +204,13 @@ static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
|
||||||
g_free(xendev->protocol);
|
g_free(xendev->protocol);
|
||||||
xendev->protocol = xenstore_read_fe_str(xendev, "protocol");
|
xendev->protocol = xenstore_read_fe_str(xendev, "protocol");
|
||||||
if (xendev->protocol) {
|
if (xendev->protocol) {
|
||||||
xen_be_printf(xendev, 1, "frontend protocol: %s\n", xendev->protocol);
|
xen_pv_printf(xendev, 1, "frontend protocol: %s\n",
|
||||||
|
xendev->protocol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
xen_be_printf(xendev, 2, "frontend update: %s\n", node);
|
xen_pv_printf(xendev, 2, "frontend update: %s\n", node);
|
||||||
if (xendev->ops->frontend_changed) {
|
if (xendev->ops->frontend_changed) {
|
||||||
xendev->ops->frontend_changed(xendev, node);
|
xendev->ops->frontend_changed(xendev, node);
|
||||||
}
|
}
|
||||||
|
@ -414,26 +234,26 @@ static int xen_be_try_setup(struct XenDevice *xendev)
|
||||||
int be_state;
|
int be_state;
|
||||||
|
|
||||||
if (xenstore_read_be_int(xendev, "state", &be_state) == -1) {
|
if (xenstore_read_be_int(xendev, "state", &be_state) == -1) {
|
||||||
xen_be_printf(xendev, 0, "reading backend state failed\n");
|
xen_pv_printf(xendev, 0, "reading backend state failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (be_state != XenbusStateInitialising) {
|
if (be_state != XenbusStateInitialising) {
|
||||||
xen_be_printf(xendev, 0, "initial backend state is wrong (%s)\n",
|
xen_pv_printf(xendev, 0, "initial backend state is wrong (%s)\n",
|
||||||
xenbus_strstate(be_state));
|
xenbus_strstate(be_state));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
xendev->fe = xenstore_read_be_str(xendev, "frontend");
|
xendev->fe = xenstore_read_be_str(xendev, "frontend");
|
||||||
if (xendev->fe == NULL) {
|
if (xendev->fe == NULL) {
|
||||||
xen_be_printf(xendev, 0, "reading frontend path failed\n");
|
xen_pv_printf(xendev, 0, "reading frontend path failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup frontend watch */
|
/* setup frontend watch */
|
||||||
snprintf(token, sizeof(token), "fe:%p", xendev);
|
snprintf(token, sizeof(token), "fe:%p", xendev);
|
||||||
if (!xs_watch(xenstore, xendev->fe, token)) {
|
if (!xs_watch(xenstore, xendev->fe, token)) {
|
||||||
xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n",
|
xen_pv_printf(xendev, 0, "watching frontend path (%s) failed\n",
|
||||||
xendev->fe);
|
xendev->fe);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -457,7 +277,7 @@ static int xen_be_try_init(struct XenDevice *xendev)
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (!xendev->online) {
|
if (!xendev->online) {
|
||||||
xen_be_printf(xendev, 1, "not online\n");
|
xen_pv_printf(xendev, 1, "not online\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,7 +285,7 @@ static int xen_be_try_init(struct XenDevice *xendev)
|
||||||
rc = xendev->ops->init(xendev);
|
rc = xendev->ops->init(xendev);
|
||||||
}
|
}
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
xen_be_printf(xendev, 1, "init() failed\n");
|
xen_pv_printf(xendev, 1, "init() failed\n");
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,9 +308,9 @@ static int xen_be_try_initialise(struct XenDevice *xendev)
|
||||||
if (xendev->fe_state != XenbusStateInitialised &&
|
if (xendev->fe_state != XenbusStateInitialised &&
|
||||||
xendev->fe_state != XenbusStateConnected) {
|
xendev->fe_state != XenbusStateConnected) {
|
||||||
if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
|
if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
|
||||||
xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
|
xen_pv_printf(xendev, 2, "frontend not ready, ignoring\n");
|
||||||
} else {
|
} else {
|
||||||
xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
|
xen_pv_printf(xendev, 2, "frontend not ready (yet)\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -499,7 +319,7 @@ static int xen_be_try_initialise(struct XenDevice *xendev)
|
||||||
rc = xendev->ops->initialise(xendev);
|
rc = xendev->ops->initialise(xendev);
|
||||||
}
|
}
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
xen_be_printf(xendev, 0, "initialise() failed\n");
|
xen_pv_printf(xendev, 0, "initialise() failed\n");
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,9 +340,9 @@ static void xen_be_try_connected(struct XenDevice *xendev)
|
||||||
|
|
||||||
if (xendev->fe_state != XenbusStateConnected) {
|
if (xendev->fe_state != XenbusStateConnected) {
|
||||||
if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
|
if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
|
||||||
xen_be_printf(xendev, 2, "frontend not ready, ignoring\n");
|
xen_pv_printf(xendev, 2, "frontend not ready, ignoring\n");
|
||||||
} else {
|
} else {
|
||||||
xen_be_printf(xendev, 2, "frontend not ready (yet)\n");
|
xen_pv_printf(xendev, 2, "frontend not ready (yet)\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -556,7 +376,7 @@ static int xen_be_try_reset(struct XenDevice *xendev)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
xen_be_printf(xendev, 1, "device reset (for re-connect)\n");
|
xen_pv_printf(xendev, 1, "device reset (for re-connect)\n");
|
||||||
xen_be_set_state(xendev, XenbusStateInitialising);
|
xen_be_set_state(xendev, XenbusStateInitialising);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -617,7 +437,8 @@ static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
|
||||||
snprintf(token, sizeof(token), "be:%p:%d:%p", type, dom, ops);
|
snprintf(token, sizeof(token), "be:%p:%d:%p", type, dom, ops);
|
||||||
snprintf(path, sizeof(path), "backend/%s/%d", type, dom);
|
snprintf(path, sizeof(path), "backend/%s/%d", type, dom);
|
||||||
if (!xs_watch(xenstore, path, token)) {
|
if (!xs_watch(xenstore, path, token)) {
|
||||||
xen_be_printf(NULL, 0, "xen be: watching backend path (%s) failed\n", path);
|
xen_pv_printf(NULL, 0, "xen be: watching backend path (%s) failed\n",
|
||||||
|
path);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,8 +458,8 @@ static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xenstore_update_be(char *watch, char *type, int dom,
|
void xenstore_update_be(char *watch, char *type, int dom,
|
||||||
struct XenDevOps *ops)
|
struct XenDevOps *ops)
|
||||||
{
|
{
|
||||||
struct XenDevice *xendev;
|
struct XenDevice *xendev;
|
||||||
char path[XEN_BUFSIZE], *bepath;
|
char path[XEN_BUFSIZE], *bepath;
|
||||||
|
@ -662,7 +483,7 @@ static void xenstore_update_be(char *watch, char *type, int dom,
|
||||||
if (xendev != NULL) {
|
if (xendev != NULL) {
|
||||||
bepath = xs_read(xenstore, 0, xendev->be, &len);
|
bepath = xs_read(xenstore, 0, xendev->be, &len);
|
||||||
if (bepath == NULL) {
|
if (bepath == NULL) {
|
||||||
xen_be_del_xendev(xendev);
|
xen_pv_del_xendev(xendev);
|
||||||
} else {
|
} else {
|
||||||
free(bepath);
|
free(bepath);
|
||||||
xen_be_backend_changed(xendev, path);
|
xen_be_backend_changed(xendev, path);
|
||||||
|
@ -671,7 +492,7 @@ static void xenstore_update_be(char *watch, char *type, int dom,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xenstore_update_fe(char *watch, struct XenDevice *xendev)
|
void xenstore_update_fe(char *watch, struct XenDevice *xendev)
|
||||||
{
|
{
|
||||||
char *node;
|
char *node;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
@ -688,56 +509,13 @@ static void xenstore_update_fe(char *watch, struct XenDevice *xendev)
|
||||||
xen_be_frontend_changed(xendev, node);
|
xen_be_frontend_changed(xendev, node);
|
||||||
xen_be_check_state(xendev);
|
xen_be_check_state(xendev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xenstore_update(void *unused)
|
|
||||||
{
|
|
||||||
char **vec = NULL;
|
|
||||||
intptr_t type, ops, ptr;
|
|
||||||
unsigned int dom, count;
|
|
||||||
|
|
||||||
vec = xs_read_watch(xenstore, &count);
|
|
||||||
if (vec == NULL) {
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sscanf(vec[XS_WATCH_TOKEN], "be:%" PRIxPTR ":%d:%" PRIxPTR,
|
|
||||||
&type, &dom, &ops) == 3) {
|
|
||||||
xenstore_update_be(vec[XS_WATCH_PATH], (void*)type, dom, (void*)ops);
|
|
||||||
}
|
|
||||||
if (sscanf(vec[XS_WATCH_TOKEN], "fe:%" PRIxPTR, &ptr) == 1) {
|
|
||||||
xenstore_update_fe(vec[XS_WATCH_PATH], (void*)ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
free(vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void xen_be_evtchn_event(void *opaque)
|
|
||||||
{
|
|
||||||
struct XenDevice *xendev = opaque;
|
|
||||||
evtchn_port_t port;
|
|
||||||
|
|
||||||
port = xenevtchn_pending(xendev->evtchndev);
|
|
||||||
if (port != xendev->local_port) {
|
|
||||||
xen_be_printf(xendev, 0,
|
|
||||||
"xenevtchn_pending returned %d (expected %d)\n",
|
|
||||||
port, xendev->local_port);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
xenevtchn_unmask(xendev->evtchndev, port);
|
|
||||||
|
|
||||||
if (xendev->ops->event) {
|
|
||||||
xendev->ops->event(xendev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
int xen_be_init(void)
|
int xen_be_init(void)
|
||||||
{
|
{
|
||||||
xenstore = xs_daemon_open();
|
xenstore = xs_daemon_open();
|
||||||
if (!xenstore) {
|
if (!xenstore) {
|
||||||
xen_be_printf(NULL, 0, "can't connect to xenstored\n");
|
xen_pv_printf(NULL, 0, "can't connect to xenstored\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,69 +576,15 @@ int xen_be_bind_evtchn(struct XenDevice *xendev)
|
||||||
xendev->local_port = xenevtchn_bind_interdomain
|
xendev->local_port = xenevtchn_bind_interdomain
|
||||||
(xendev->evtchndev, xendev->dom, xendev->remote_port);
|
(xendev->evtchndev, xendev->dom, xendev->remote_port);
|
||||||
if (xendev->local_port == -1) {
|
if (xendev->local_port == -1) {
|
||||||
xen_be_printf(xendev, 0, "xenevtchn_bind_interdomain failed\n");
|
xen_pv_printf(xendev, 0, "xenevtchn_bind_interdomain failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
xen_be_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port);
|
xen_pv_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port);
|
||||||
qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev),
|
qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev),
|
||||||
xen_be_evtchn_event, NULL, xendev);
|
xen_pv_evtchn_event, NULL, xendev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void xen_be_unbind_evtchn(struct XenDevice *xendev)
|
|
||||||
{
|
|
||||||
if (xendev->local_port == -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
|
|
||||||
xenevtchn_unbind(xendev->evtchndev, xendev->local_port);
|
|
||||||
xen_be_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port);
|
|
||||||
xendev->local_port = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xen_be_send_notify(struct XenDevice *xendev)
|
|
||||||
{
|
|
||||||
return xenevtchn_notify(xendev->evtchndev, xendev->local_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* msg_level:
|
|
||||||
* 0 == errors (stderr + logfile).
|
|
||||||
* 1 == informative debug messages (logfile only).
|
|
||||||
* 2 == noisy debug messages (logfile only).
|
|
||||||
* 3 == will flood your log (logfile only).
|
|
||||||
*/
|
|
||||||
void xen_be_printf(struct XenDevice *xendev, int msg_level, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
if (xendev) {
|
|
||||||
if (msg_level > xendev->debug) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
qemu_log("xen be: %s: ", xendev->name);
|
|
||||||
if (msg_level == 0) {
|
|
||||||
fprintf(stderr, "xen be: %s: ", xendev->name);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (msg_level > debug) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
qemu_log("xen be core: ");
|
|
||||||
if (msg_level == 0) {
|
|
||||||
fprintf(stderr, "xen be core: ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
va_start(args, fmt);
|
|
||||||
qemu_log_vprintf(fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
if (msg_level == 0) {
|
|
||||||
va_start(args, fmt);
|
|
||||||
vfprintf(stderr, fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
qemu_log_flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int xen_sysdev_init(SysBusDevice *dev)
|
static int xen_sysdev_init(SysBusDevice *dev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,7 +55,7 @@ int xen_config_dev_blk(DriveInfo *disk)
|
||||||
const char *filename = qemu_opt_get(disk->opts, "file");
|
const char *filename = qemu_opt_get(disk->opts, "file");
|
||||||
|
|
||||||
snprintf(device_name, sizeof(device_name), "xvd%c", 'a' + disk->unit);
|
snprintf(device_name, sizeof(device_name), "xvd%c", 'a' + disk->unit);
|
||||||
xen_be_printf(NULL, 1, "config disk %d [%s]: %s\n",
|
xen_pv_printf(NULL, 1, "config disk %d [%s]: %s\n",
|
||||||
disk->unit, device_name, filename);
|
disk->unit, device_name, filename);
|
||||||
xen_config_dev_dirs("vbd", "qdisk", vdev, fe, be, sizeof(fe));
|
xen_config_dev_dirs("vbd", "qdisk", vdev, fe, be, sizeof(fe));
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ int xen_config_dev_nic(NICInfo *nic)
|
||||||
snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
|
snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
nic->macaddr.a[0], nic->macaddr.a[1], nic->macaddr.a[2],
|
nic->macaddr.a[0], nic->macaddr.a[1], nic->macaddr.a[2],
|
||||||
nic->macaddr.a[3], nic->macaddr.a[4], nic->macaddr.a[5]);
|
nic->macaddr.a[3], nic->macaddr.a[4], nic->macaddr.a[5]);
|
||||||
xen_be_printf(NULL, 1, "config nic %d: mac=\"%s\"\n", vlan_id, mac);
|
xen_pv_printf(NULL, 1, "config nic %d: mac=\"%s\"\n", vlan_id, mac);
|
||||||
xen_config_dev_dirs("vif", "qnic", vlan_id, fe, be, sizeof(fe));
|
xen_config_dev_dirs("vif", "qnic", vlan_id, fe, be, sizeof(fe));
|
||||||
|
|
||||||
/* frontend */
|
/* frontend */
|
||||||
|
|
316
hw/xen/xen_pvdev.c
Normal file
316
hw/xen/xen_pvdev.c
Normal file
|
@ -0,0 +1,316 @@
|
||||||
|
/*
|
||||||
|
* Xen para-virtualization device
|
||||||
|
*
|
||||||
|
* (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qemu/osdep.h"
|
||||||
|
|
||||||
|
#include "hw/xen/xen_backend.h"
|
||||||
|
#include "hw/xen/xen_pvdev.h"
|
||||||
|
|
||||||
|
/* private */
|
||||||
|
static int debug;
|
||||||
|
|
||||||
|
struct xs_dirs {
|
||||||
|
char *xs_dir;
|
||||||
|
QTAILQ_ENTRY(xs_dirs) list;
|
||||||
|
};
|
||||||
|
|
||||||
|
static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup =
|
||||||
|
QTAILQ_HEAD_INITIALIZER(xs_cleanup);
|
||||||
|
|
||||||
|
static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs =
|
||||||
|
QTAILQ_HEAD_INITIALIZER(xendevs);
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static void xenstore_cleanup_dir(char *dir)
|
||||||
|
{
|
||||||
|
struct xs_dirs *d;
|
||||||
|
|
||||||
|
d = g_malloc(sizeof(*d));
|
||||||
|
d->xs_dir = dir;
|
||||||
|
QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xen_config_cleanup(void)
|
||||||
|
{
|
||||||
|
struct xs_dirs *d;
|
||||||
|
|
||||||
|
QTAILQ_FOREACH(d, &xs_cleanup, list) {
|
||||||
|
xs_rm(xenstore, 0, d->xs_dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int xenstore_mkdir(char *path, int p)
|
||||||
|
{
|
||||||
|
struct xs_permissions perms[2] = {
|
||||||
|
{
|
||||||
|
.id = 0, /* set owner: dom0 */
|
||||||
|
}, {
|
||||||
|
.id = xen_domid,
|
||||||
|
.perms = p,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!xs_mkdir(xenstore, 0, path)) {
|
||||||
|
xen_pv_printf(NULL, 0, "xs_mkdir %s: failed\n", path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
xenstore_cleanup_dir(g_strdup(path));
|
||||||
|
|
||||||
|
if (!xs_set_permissions(xenstore, 0, path, perms, 2)) {
|
||||||
|
xen_pv_printf(NULL, 0, "xs_set_permissions %s: failed\n", path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xenstore_write_str(const char *base, const char *node, const char *val)
|
||||||
|
{
|
||||||
|
char abspath[XEN_BUFSIZE];
|
||||||
|
|
||||||
|
snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
|
||||||
|
if (!xs_write(xenstore, 0, abspath, val, strlen(val))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *xenstore_read_str(const char *base, const char *node)
|
||||||
|
{
|
||||||
|
char abspath[XEN_BUFSIZE];
|
||||||
|
unsigned int len;
|
||||||
|
char *str, *ret = NULL;
|
||||||
|
|
||||||
|
snprintf(abspath, sizeof(abspath), "%s/%s", base, node);
|
||||||
|
str = xs_read(xenstore, 0, abspath, &len);
|
||||||
|
if (str != NULL) {
|
||||||
|
/* move to qemu-allocated memory to make sure
|
||||||
|
* callers can savely g_free() stuff. */
|
||||||
|
ret = g_strdup(str);
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xenstore_write_int(const char *base, const char *node, int ival)
|
||||||
|
{
|
||||||
|
char val[12];
|
||||||
|
|
||||||
|
snprintf(val, sizeof(val), "%d", ival);
|
||||||
|
return xenstore_write_str(base, node, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
int xenstore_write_int64(const char *base, const char *node, int64_t ival)
|
||||||
|
{
|
||||||
|
char val[21];
|
||||||
|
|
||||||
|
snprintf(val, sizeof(val), "%"PRId64, ival);
|
||||||
|
return xenstore_write_str(base, node, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
int xenstore_read_int(const char *base, const char *node, int *ival)
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
int rc = -1;
|
||||||
|
|
||||||
|
val = xenstore_read_str(base, node);
|
||||||
|
if (val && 1 == sscanf(val, "%d", ival)) {
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
g_free(val);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xenstore_read_uint64(const char *base, const char *node, uint64_t *uval)
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
int rc = -1;
|
||||||
|
|
||||||
|
val = xenstore_read_str(base, node);
|
||||||
|
if (val && 1 == sscanf(val, "%"SCNu64, uval)) {
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
g_free(val);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xenstore_update(void *unused)
|
||||||
|
{
|
||||||
|
char **vec = NULL;
|
||||||
|
intptr_t type, ops, ptr;
|
||||||
|
unsigned int dom, count;
|
||||||
|
|
||||||
|
vec = xs_read_watch(xenstore, &count);
|
||||||
|
if (vec == NULL) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sscanf(vec[XS_WATCH_TOKEN], "be:%" PRIxPTR ":%d:%" PRIxPTR,
|
||||||
|
&type, &dom, &ops) == 3) {
|
||||||
|
xenstore_update_be(vec[XS_WATCH_PATH], (void *)type, dom, (void*)ops);
|
||||||
|
}
|
||||||
|
if (sscanf(vec[XS_WATCH_TOKEN], "fe:%" PRIxPTR, &ptr) == 1) {
|
||||||
|
xenstore_update_fe(vec[XS_WATCH_PATH], (void *)ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
free(vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *xenbus_strstate(enum xenbus_state state)
|
||||||
|
{
|
||||||
|
static const char *const name[] = {
|
||||||
|
[XenbusStateUnknown] = "Unknown",
|
||||||
|
[XenbusStateInitialising] = "Initialising",
|
||||||
|
[XenbusStateInitWait] = "InitWait",
|
||||||
|
[XenbusStateInitialised] = "Initialised",
|
||||||
|
[XenbusStateConnected] = "Connected",
|
||||||
|
[XenbusStateClosing] = "Closing",
|
||||||
|
[XenbusStateClosed] = "Closed",
|
||||||
|
};
|
||||||
|
return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* msg_level:
|
||||||
|
* 0 == errors (stderr + logfile).
|
||||||
|
* 1 == informative debug messages (logfile only).
|
||||||
|
* 2 == noisy debug messages (logfile only).
|
||||||
|
* 3 == will flood your log (logfile only).
|
||||||
|
*/
|
||||||
|
void xen_pv_printf(struct XenDevice *xendev, int msg_level,
|
||||||
|
const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
if (xendev) {
|
||||||
|
if (msg_level > xendev->debug) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qemu_log("xen be: %s: ", xendev->name);
|
||||||
|
if (msg_level == 0) {
|
||||||
|
fprintf(stderr, "xen be: %s: ", xendev->name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (msg_level > debug) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qemu_log("xen be core: ");
|
||||||
|
if (msg_level == 0) {
|
||||||
|
fprintf(stderr, "xen be core: ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
va_start(args, fmt);
|
||||||
|
qemu_log_vprintf(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
if (msg_level == 0) {
|
||||||
|
va_start(args, fmt);
|
||||||
|
vfprintf(stderr, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
qemu_log_flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void xen_pv_evtchn_event(void *opaque)
|
||||||
|
{
|
||||||
|
struct XenDevice *xendev = opaque;
|
||||||
|
evtchn_port_t port;
|
||||||
|
|
||||||
|
port = xenevtchn_pending(xendev->evtchndev);
|
||||||
|
if (port != xendev->local_port) {
|
||||||
|
xen_pv_printf(xendev, 0,
|
||||||
|
"xenevtchn_pending returned %d (expected %d)\n",
|
||||||
|
port, xendev->local_port);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xenevtchn_unmask(xendev->evtchndev, port);
|
||||||
|
|
||||||
|
if (xendev->ops->event) {
|
||||||
|
xendev->ops->event(xendev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xen_pv_unbind_evtchn(struct XenDevice *xendev)
|
||||||
|
{
|
||||||
|
if (xendev->local_port == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
|
||||||
|
xenevtchn_unbind(xendev->evtchndev, xendev->local_port);
|
||||||
|
xen_pv_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port);
|
||||||
|
xendev->local_port = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xen_pv_send_notify(struct XenDevice *xendev)
|
||||||
|
{
|
||||||
|
return xenevtchn_notify(xendev->evtchndev, xendev->local_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------- */
|
||||||
|
|
||||||
|
struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev)
|
||||||
|
{
|
||||||
|
struct XenDevice *xendev;
|
||||||
|
|
||||||
|
QTAILQ_FOREACH(xendev, &xendevs, next) {
|
||||||
|
if (xendev->dom != dom) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (xendev->dev != dev) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(xendev->type, type) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return xendev;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* release xen backend device.
|
||||||
|
*/
|
||||||
|
void xen_pv_del_xendev(struct XenDevice *xendev)
|
||||||
|
{
|
||||||
|
if (xendev->ops->free) {
|
||||||
|
xendev->ops->free(xendev);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xendev->fe) {
|
||||||
|
char token[XEN_BUFSIZE];
|
||||||
|
snprintf(token, sizeof(token), "fe:%p", xendev);
|
||||||
|
xs_unwatch(xenstore, xendev->fe, token);
|
||||||
|
g_free(xendev->fe);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xendev->evtchndev != NULL) {
|
||||||
|
xenevtchn_close(xendev->evtchndev);
|
||||||
|
}
|
||||||
|
if (xendev->gnttabdev != NULL) {
|
||||||
|
xengnttab_close(xendev->gnttabdev);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTAILQ_REMOVE(&xendevs, xendev, next);
|
||||||
|
g_free(xendev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xen_pv_insert_xendev(struct XenDevice *xendev)
|
||||||
|
{
|
||||||
|
QTAILQ_INSERT_TAIL(&xendevs, xendev, next);
|
||||||
|
}
|
|
@ -2,60 +2,10 @@
|
||||||
#define QEMU_HW_XEN_BACKEND_H
|
#define QEMU_HW_XEN_BACKEND_H
|
||||||
|
|
||||||
#include "hw/xen/xen_common.h"
|
#include "hw/xen/xen_common.h"
|
||||||
|
#include "hw/xen/xen_pvdev.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "net/net.h"
|
#include "net/net.h"
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
|
|
||||||
#define XEN_BUFSIZE 1024
|
|
||||||
|
|
||||||
struct XenDevice;
|
|
||||||
|
|
||||||
/* driver uses grant tables -> open gntdev device (xendev->gnttabdev) */
|
|
||||||
#define DEVOPS_FLAG_NEED_GNTDEV 1
|
|
||||||
/* don't expect frontend doing correct state transitions (aka console quirk) */
|
|
||||||
#define DEVOPS_FLAG_IGNORE_STATE 2
|
|
||||||
|
|
||||||
struct XenDevOps {
|
|
||||||
size_t size;
|
|
||||||
uint32_t flags;
|
|
||||||
void (*alloc)(struct XenDevice *xendev);
|
|
||||||
int (*init)(struct XenDevice *xendev);
|
|
||||||
int (*initialise)(struct XenDevice *xendev);
|
|
||||||
void (*connected)(struct XenDevice *xendev);
|
|
||||||
void (*event)(struct XenDevice *xendev);
|
|
||||||
void (*disconnect)(struct XenDevice *xendev);
|
|
||||||
int (*free)(struct XenDevice *xendev);
|
|
||||||
void (*backend_changed)(struct XenDevice *xendev, const char *node);
|
|
||||||
void (*frontend_changed)(struct XenDevice *xendev, const char *node);
|
|
||||||
int (*backend_register)(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct XenDevice {
|
|
||||||
const char *type;
|
|
||||||
int dom;
|
|
||||||
int dev;
|
|
||||||
char name[64];
|
|
||||||
int debug;
|
|
||||||
|
|
||||||
enum xenbus_state be_state;
|
|
||||||
enum xenbus_state fe_state;
|
|
||||||
int online;
|
|
||||||
char be[XEN_BUFSIZE];
|
|
||||||
char *fe;
|
|
||||||
char *protocol;
|
|
||||||
int remote_port;
|
|
||||||
int local_port;
|
|
||||||
|
|
||||||
xenevtchn_handle *evtchndev;
|
|
||||||
xengnttab_handle *gnttabdev;
|
|
||||||
|
|
||||||
struct XenDevOps *ops;
|
|
||||||
QTAILQ_ENTRY(XenDevice) next;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* variables */
|
/* variables */
|
||||||
extern xc_interface *xen_xc;
|
extern xc_interface *xen_xc;
|
||||||
extern xenforeignmemory_handle *xen_fmem;
|
extern xenforeignmemory_handle *xen_fmem;
|
||||||
|
@ -63,26 +13,20 @@ extern struct xs_handle *xenstore;
|
||||||
extern const char *xen_protocol;
|
extern const char *xen_protocol;
|
||||||
extern DeviceState *xen_sysdev;
|
extern DeviceState *xen_sysdev;
|
||||||
|
|
||||||
/* xenstore helper functions */
|
|
||||||
int xenstore_mkdir(char *path, int p);
|
int xenstore_mkdir(char *path, int p);
|
||||||
int xenstore_write_str(const char *base, const char *node, const char *val);
|
|
||||||
int xenstore_write_int(const char *base, const char *node, int ival);
|
|
||||||
int xenstore_write_int64(const char *base, const char *node, int64_t ival);
|
|
||||||
char *xenstore_read_str(const char *base, const char *node);
|
|
||||||
int xenstore_read_int(const char *base, const char *node, int *ival);
|
|
||||||
|
|
||||||
int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val);
|
int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val);
|
||||||
int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival);
|
int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival);
|
||||||
int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival);
|
int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival);
|
||||||
char *xenstore_read_be_str(struct XenDevice *xendev, const char *node);
|
char *xenstore_read_be_str(struct XenDevice *xendev, const char *node);
|
||||||
int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival);
|
int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival);
|
||||||
|
void xenstore_update_fe(char *watch, struct XenDevice *xendev);
|
||||||
|
void xenstore_update_be(char *watch, char *type, int dom,
|
||||||
|
struct XenDevOps *ops);
|
||||||
char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node);
|
char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node);
|
||||||
int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival);
|
int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival);
|
||||||
int xenstore_read_uint64(const char *base, const char *node, uint64_t *uval);
|
int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node,
|
||||||
int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node, uint64_t *uval);
|
uint64_t *uval);
|
||||||
|
|
||||||
const char *xenbus_strstate(enum xenbus_state state);
|
|
||||||
struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev);
|
|
||||||
void xen_be_check_state(struct XenDevice *xendev);
|
void xen_be_check_state(struct XenDevice *xendev);
|
||||||
|
|
||||||
/* xen backend driver bits */
|
/* xen backend driver bits */
|
||||||
|
@ -91,10 +35,6 @@ void xen_be_register_common(void);
|
||||||
int xen_be_register(const char *type, struct XenDevOps *ops);
|
int xen_be_register(const char *type, struct XenDevOps *ops);
|
||||||
int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state);
|
int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state);
|
||||||
int xen_be_bind_evtchn(struct XenDevice *xendev);
|
int xen_be_bind_evtchn(struct XenDevice *xendev);
|
||||||
void xen_be_unbind_evtchn(struct XenDevice *xendev);
|
|
||||||
int xen_be_send_notify(struct XenDevice *xendev);
|
|
||||||
void xen_be_printf(struct XenDevice *xendev, int msg_level, const char *fmt, ...)
|
|
||||||
GCC_FMT_ATTR(3, 4);
|
|
||||||
|
|
||||||
/* actual backend drivers */
|
/* actual backend drivers */
|
||||||
extern struct XenDevOps xen_console_ops; /* xen_console.c */
|
extern struct XenDevOps xen_console_ops; /* xen_console.c */
|
||||||
|
|
78
include/hw/xen/xen_pvdev.h
Normal file
78
include/hw/xen/xen_pvdev.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
#ifndef QEMU_HW_XEN_PVDEV_H
|
||||||
|
#define QEMU_HW_XEN_PVDEV_H
|
||||||
|
|
||||||
|
#include "hw/xen/xen_common.h"
|
||||||
|
/* ------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#define XEN_BUFSIZE 1024
|
||||||
|
|
||||||
|
struct XenDevice;
|
||||||
|
|
||||||
|
/* driver uses grant tables -> open gntdev device (xendev->gnttabdev) */
|
||||||
|
#define DEVOPS_FLAG_NEED_GNTDEV 1
|
||||||
|
/* don't expect frontend doing correct state transitions (aka console quirk) */
|
||||||
|
#define DEVOPS_FLAG_IGNORE_STATE 2
|
||||||
|
|
||||||
|
struct XenDevOps {
|
||||||
|
size_t size;
|
||||||
|
uint32_t flags;
|
||||||
|
void (*alloc)(struct XenDevice *xendev);
|
||||||
|
int (*init)(struct XenDevice *xendev);
|
||||||
|
int (*initialise)(struct XenDevice *xendev);
|
||||||
|
void (*connected)(struct XenDevice *xendev);
|
||||||
|
void (*event)(struct XenDevice *xendev);
|
||||||
|
void (*disconnect)(struct XenDevice *xendev);
|
||||||
|
int (*free)(struct XenDevice *xendev);
|
||||||
|
void (*backend_changed)(struct XenDevice *xendev, const char *node);
|
||||||
|
void (*frontend_changed)(struct XenDevice *xendev, const char *node);
|
||||||
|
int (*backend_register)(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct XenDevice {
|
||||||
|
const char *type;
|
||||||
|
int dom;
|
||||||
|
int dev;
|
||||||
|
char name[64];
|
||||||
|
int debug;
|
||||||
|
|
||||||
|
enum xenbus_state be_state;
|
||||||
|
enum xenbus_state fe_state;
|
||||||
|
int online;
|
||||||
|
char be[XEN_BUFSIZE];
|
||||||
|
char *fe;
|
||||||
|
char *protocol;
|
||||||
|
int remote_port;
|
||||||
|
int local_port;
|
||||||
|
|
||||||
|
xenevtchn_handle *evtchndev;
|
||||||
|
xengnttab_handle *gnttabdev;
|
||||||
|
|
||||||
|
struct XenDevOps *ops;
|
||||||
|
QTAILQ_ENTRY(XenDevice) next;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* xenstore helper functions */
|
||||||
|
int xenstore_write_str(const char *base, const char *node, const char *val);
|
||||||
|
int xenstore_write_int(const char *base, const char *node, int ival);
|
||||||
|
int xenstore_write_int64(const char *base, const char *node, int64_t ival);
|
||||||
|
char *xenstore_read_str(const char *base, const char *node);
|
||||||
|
int xenstore_read_int(const char *base, const char *node, int *ival);
|
||||||
|
int xenstore_read_uint64(const char *base, const char *node, uint64_t *uval);
|
||||||
|
void xenstore_update(void *unused);
|
||||||
|
|
||||||
|
const char *xenbus_strstate(enum xenbus_state state);
|
||||||
|
|
||||||
|
void xen_pv_evtchn_event(void *opaque);
|
||||||
|
void xen_pv_insert_xendev(struct XenDevice *xendev);
|
||||||
|
void xen_pv_del_xendev(struct XenDevice *xendev);
|
||||||
|
struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev);
|
||||||
|
|
||||||
|
void xen_pv_unbind_evtchn(struct XenDevice *xendev);
|
||||||
|
int xen_pv_send_notify(struct XenDevice *xendev);
|
||||||
|
|
||||||
|
void xen_pv_printf(struct XenDevice *xendev, int msg_level,
|
||||||
|
const char *fmt, ...) GCC_FMT_ATTR(3, 4);
|
||||||
|
|
||||||
|
#endif /* QEMU_HW_XEN_PVDEV_H */
|
|
@ -116,12 +116,12 @@ static int xen_init(MachineState *ms)
|
||||||
{
|
{
|
||||||
xen_xc = xc_interface_open(0, 0, 0);
|
xen_xc = xc_interface_open(0, 0, 0);
|
||||||
if (xen_xc == NULL) {
|
if (xen_xc == NULL) {
|
||||||
xen_be_printf(NULL, 0, "can't open xen interface\n");
|
xen_pv_printf(NULL, 0, "can't open xen interface\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
xen_fmem = xenforeignmemory_open(0, 0);
|
xen_fmem = xenforeignmemory_open(0, 0);
|
||||||
if (xen_fmem == NULL) {
|
if (xen_fmem == NULL) {
|
||||||
xen_be_printf(NULL, 0, "can't open xen fmem interface\n");
|
xen_pv_printf(NULL, 0, "can't open xen fmem interface\n");
|
||||||
xc_interface_close(xen_xc);
|
xc_interface_close(xen_xc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue