From: Anthony PERARD <anthony.perard@citrix.com>
To: qemu-devel@nongnu.org
Cc: xen-devel@lists.xenproject.org,
Paul Durrant <paul.durrant@citrix.com>,
Anthony PERARD <anthony.perard@citrix.com>
Subject: [Qemu-devel] [PULL 08/25] xen: add grant table interface for XenDevice-s
Date: Thu, 10 Jan 2019 13:49:00 +0000 [thread overview]
Message-ID: <20190110134917.16425-9-anthony.perard@citrix.com> (raw)
In-Reply-To: <20190110134917.16425-1-anthony.perard@citrix.com>
From: Paul Durrant <paul.durrant@citrix.com>
The legacy PV backend infrastructure provides functions to map, unmap and
copy pages granted by frontends. Similar functionality will be required
by XenDevice implementations so this patch adds the necessary support.
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: Anthony Perard <anthony.perard@citrix.com>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
hw/xen/xen-bus.c | 146 +++++++++++++++++++++++++++++++++++++++
include/hw/xen/xen-bus.h | 25 +++++++
2 files changed, 171 insertions(+)
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 5e19592190..faa9fd3577 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -485,6 +485,138 @@ static void xen_device_frontend_destroy(XenDevice *xendev)
}
}
+void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
+ Error **errp)
+{
+ if (xengnttab_set_max_grants(xendev->xgth, nr_refs)) {
+ error_setg_errno(errp, errno, "xengnttab_set_max_grants failed");
+ }
+}
+
+void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
+ unsigned int nr_refs, int prot,
+ Error **errp)
+{
+ void *map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_refs,
+ xendev->frontend_id, refs,
+ prot);
+
+ if (!map) {
+ error_setg_errno(errp, errno,
+ "xengnttab_map_domain_grant_refs failed");
+ }
+
+ return map;
+}
+
+void xen_device_unmap_grant_refs(XenDevice *xendev, void *map,
+ unsigned int nr_refs, Error **errp)
+{
+ if (xengnttab_unmap(xendev->xgth, map, nr_refs)) {
+ error_setg_errno(errp, errno, "xengnttab_unmap failed");
+ }
+}
+
+static void compat_copy_grant_refs(XenDevice *xendev, bool to_domain,
+ XenDeviceGrantCopySegment segs[],
+ unsigned int nr_segs, Error **errp)
+{
+ uint32_t *refs = g_new(uint32_t, nr_segs);
+ int prot = to_domain ? PROT_WRITE : PROT_READ;
+ void *map;
+ unsigned int i;
+
+ for (i = 0; i < nr_segs; i++) {
+ XenDeviceGrantCopySegment *seg = &segs[i];
+
+ refs[i] = to_domain ? seg->dest.foreign.ref :
+ seg->source.foreign.ref;
+ }
+
+ map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_segs,
+ xendev->frontend_id, refs,
+ prot);
+ if (!map) {
+ error_setg_errno(errp, errno,
+ "xengnttab_map_domain_grant_refs failed");
+ goto done;
+ }
+
+ for (i = 0; i < nr_segs; i++) {
+ XenDeviceGrantCopySegment *seg = &segs[i];
+ void *page = map + (i * XC_PAGE_SIZE);
+
+ if (to_domain) {
+ memcpy(page + seg->dest.foreign.offset, seg->source.virt,
+ seg->len);
+ } else {
+ memcpy(seg->dest.virt, page + seg->source.foreign.offset,
+ seg->len);
+ }
+ }
+
+ if (xengnttab_unmap(xendev->xgth, map, nr_segs)) {
+ error_setg_errno(errp, errno, "xengnttab_unmap failed");
+ }
+
+done:
+ g_free(refs);
+}
+
+void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
+ XenDeviceGrantCopySegment segs[],
+ unsigned int nr_segs, Error **errp)
+{
+ xengnttab_grant_copy_segment_t *xengnttab_segs;
+ unsigned int i;
+
+ if (!xendev->feature_grant_copy) {
+ compat_copy_grant_refs(xendev, to_domain, segs, nr_segs, errp);
+ return;
+ }
+
+ xengnttab_segs = g_new0(xengnttab_grant_copy_segment_t, nr_segs);
+
+ for (i = 0; i < nr_segs; i++) {
+ XenDeviceGrantCopySegment *seg = &segs[i];
+ xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i];
+
+ if (to_domain) {
+ xengnttab_seg->flags = GNTCOPY_dest_gref;
+ xengnttab_seg->dest.foreign.domid = xendev->frontend_id;
+ xengnttab_seg->dest.foreign.ref = seg->dest.foreign.ref;
+ xengnttab_seg->dest.foreign.offset = seg->dest.foreign.offset;
+ xengnttab_seg->source.virt = seg->source.virt;
+ } else {
+ xengnttab_seg->flags = GNTCOPY_source_gref;
+ xengnttab_seg->source.foreign.domid = xendev->frontend_id;
+ xengnttab_seg->source.foreign.ref = seg->source.foreign.ref;
+ xengnttab_seg->source.foreign.offset =
+ seg->source.foreign.offset;
+ xengnttab_seg->dest.virt = seg->dest.virt;
+ }
+
+ xengnttab_seg->len = seg->len;
+ }
+
+ if (xengnttab_grant_copy(xendev->xgth, nr_segs, xengnttab_segs)) {
+ error_setg_errno(errp, errno, "xengnttab_grant_copy failed");
+ goto done;
+ }
+
+ for (i = 0; i < nr_segs; i++) {
+ xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i];
+
+ if (xengnttab_seg->status != GNTST_okay) {
+ error_setg(errp, "xengnttab_grant_copy seg[%u] failed", i);
+ break;
+ }
+ }
+
+done:
+ g_free(xengnttab_segs);
+}
+
static void xen_device_unrealize(DeviceState *dev, Error **errp)
{
XenDevice *xendev = XEN_DEVICE(dev);
@@ -509,6 +641,11 @@ static void xen_device_unrealize(DeviceState *dev, Error **errp)
xen_device_frontend_destroy(xendev);
xen_device_backend_destroy(xendev);
+ if (xendev->xgth) {
+ xengnttab_close(xendev->xgth);
+ xendev->xgth = NULL;
+ }
+
g_free(xendev->name);
xendev->name = NULL;
}
@@ -551,6 +688,15 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
trace_xen_device_realize(type, xendev->name);
+ xendev->xgth = xengnttab_open(NULL, 0);
+ if (!xendev->xgth) {
+ error_setg_errno(errp, errno, "failed xengnttab_open");
+ goto unrealize;
+ }
+
+ xendev->feature_grant_copy =
+ (xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0);
+
xen_device_backend_create(xendev, &local_err);
if (local_err) {
error_propagate(errp, local_err);
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index df73674fcd..63a09b67ee 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -24,6 +24,8 @@ typedef struct XenDevice {
enum xenbus_state backend_state, frontend_state;
Notifier exit;
XenWatch *frontend_state_watch;
+ xengnttab_handle *xgth;
+ bool feature_grant_copy;
} XenDevice;
typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp);
@@ -79,4 +81,27 @@ void xen_device_backend_set_state(XenDevice *xendev,
enum xenbus_state state);
enum xenbus_state xen_device_backend_get_state(XenDevice *xendev);
+void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
+ Error **errp);
+void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
+ unsigned int nr_refs, int prot,
+ Error **errp);
+void xen_device_unmap_grant_refs(XenDevice *xendev, void *map,
+ unsigned int nr_refs, Error **errp);
+
+typedef struct XenDeviceGrantCopySegment {
+ union {
+ void *virt;
+ struct {
+ uint32_t ref;
+ off_t offset;
+ } foreign;
+ } source, dest;
+ size_t len;
+} XenDeviceGrantCopySegment;
+
+void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
+ XenDeviceGrantCopySegment segs[],
+ unsigned int nr_segs, Error **errp);
+
#endif /* HW_XEN_BUS_H */
--
Anthony PERARD
next prev parent reply other threads:[~2019-01-10 13:50 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-10 13:48 [Qemu-devel] [PULL 00/25] xen queue Anthony PERARD
2019-01-10 13:48 ` [Qemu-devel] [PULL 01/25] hw/xen/xen_pt_graphics: Don't trust the BIOS ROM contents so much Anthony PERARD
2019-01-10 13:48 ` [Qemu-devel] [PULL 02/25] xen/pt: allow passthrough of devices with bogus interrupt pin Anthony PERARD
2019-01-10 13:48 ` [Qemu-devel] [PULL 03/25] xen: re-name XenDevice to XenLegacyDevice Anthony PERARD
2019-01-10 13:48 ` [Qemu-devel] [PULL 04/25] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Anthony PERARD
2019-01-10 13:48 ` [Qemu-devel] [PULL 05/25] xen: introduce 'xen-block', 'xen-disk' and 'xen-cdrom' Anthony PERARD
2019-01-10 13:48 ` [Qemu-devel] [PULL 06/25] xen: create xenstore areas for XenDevice-s Anthony PERARD
2019-01-10 13:48 ` [Qemu-devel] [PULL 07/25] xen: add xenstore watcher infrastructure Anthony PERARD
2019-01-10 13:49 ` Anthony PERARD [this message]
2019-01-10 13:49 ` [Qemu-devel] [PULL 09/25] xen: add event channel interface for XenDevice-s Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 10/25] xen: duplicate xen_disk.c as basis of dataplane/xen-block.c Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 11/25] xen: remove unnecessary code from dataplane/xen-block.c Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 12/25] xen: add header and build dataplane/xen-block.c Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 13/25] xen: remove 'XenBlkDev' and 'blkdev' names from dataplane/xen-block Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 14/25] xen: remove 'ioreq' struct/varable/field names from dataplane/xen-block.c Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 15/25] xen: purge 'blk' and 'ioreq' from function names in dataplane/xen-block.c Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 16/25] xen: add implementations of xen-block connect and disconnect functions Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 17/25] xen: add a mechanism to automatically create XenDevice-s Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 18/25] xen: automatically create XenBlockDevice-s Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 19/25] MAINTAINERS: add myself as a Xen maintainer Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 20/25] xen: remove the legacy 'xen_disk' backend Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 21/25] Remove broken Xen PV domain builder Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 22/25] xen: Replace few mentions of xend by libxl Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 23/25] xen-block: improve batching behaviour Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 24/25] xen-block: improve response latency Anthony PERARD
2019-01-10 13:49 ` [Qemu-devel] [PULL 25/25] xen-block: avoid repeated memory allocation Anthony PERARD
2019-01-11 13:35 ` [Qemu-devel] [PULL 00/25] xen queue Peter Maydell
2019-01-11 15:55 ` Anthony PERARD
2019-01-11 16:04 ` Peter Maydell
-- strict thread matches above, loose matches on Subject: below --
2019-01-14 13:51 [Qemu-devel] [PULL 00/25] Xen queue v2 Anthony PERARD
2019-01-14 13:51 ` [Qemu-devel] [PULL 08/25] xen: add grant table interface for XenDevice-s Anthony PERARD
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190110134917.16425-9-anthony.perard@citrix.com \
--to=anthony.perard@citrix.com \
--cc=paul.durrant@citrix.com \
--cc=qemu-devel@nongnu.org \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).