xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Paul Durrant <paul.durrant@citrix.com>
To: qemu-devel@nongnu.org, qemu-block@nongnu.org,
	xen-devel@lists.xenproject.org
Cc: Anthony Perard <anthony.perard@citrix.com>,
	Paul Durrant <paul.durrant@citrix.com>,
	Stefano Stabellini <sstabellini@kernel.org>
Subject: [PATCH v6 07/18] xen: add event channel interface for XenDevice-s
Date: Mon, 17 Dec 2018 13:30:00 +0000	[thread overview]
Message-ID: <20181217133011.31433-8-paul.durrant@citrix.com> (raw)
In-Reply-To: <20181217133011.31433-1-paul.durrant@citrix.com>

The legacy PV backend infrastructure provides functions to bind, unbind
and send notifications to event channnels. 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>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>

v2:
 - Added error pointers to notify and unbind
---
 hw/xen/xen-bus.c         | 101 +++++++++++++++++++++++++++++++++++++++
 include/hw/xen/xen-bus.h |  18 +++++++
 2 files changed, 119 insertions(+)

diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index faa9fd3577..9443f27d44 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -617,6 +617,81 @@ done:
     g_free(xengnttab_segs);
 }
 
+struct XenEventChannel {
+    unsigned int local_port;
+    XenEventHandler handler;
+    void *opaque;
+    Notifier notifier;
+};
+
+static void event_notify(Notifier *n, void *data)
+{
+    XenEventChannel *channel = container_of(n, XenEventChannel, notifier);
+    unsigned long port = (unsigned long)data;
+
+    if (port == channel->local_port) {
+        channel->handler(channel->opaque);
+    }
+}
+
+XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
+                                               unsigned int port,
+                                               XenEventHandler handler,
+                                               void *opaque, Error **errp)
+{
+    XenEventChannel *channel = g_new0(XenEventChannel, 1);
+
+    channel->local_port = xenevtchn_bind_interdomain(xendev->xeh,
+                                                     xendev->frontend_id,
+                                                     port);
+    if (xendev->local_port < 0) {
+        error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed");
+
+        g_free(channel);
+        return NULL;
+    }
+
+    channel->handler = handler;
+    channel->opaque = opaque;
+    channel->notifier.notify = event_notify;
+
+    notifier_list_add(&xendev->event_notifiers, &channel->notifier);
+
+    return channel;
+}
+
+void xen_device_notify_event_channel(XenDevice *xendev,
+                                     XenEventChannel *channel,
+                                     Error **errp)
+{
+    if (!channel) {
+        error_setg(errp, "bad channel");
+        return;
+    }
+
+    if (xenevtchn_notify(xendev->xeh, channel->local_port) < 0) {
+        error_setg_errno(errp, errno, "xenevtchn_notify failed");
+    }
+}
+
+void xen_device_unbind_event_channel(XenDevice *xendev,
+                                     XenEventChannel *channel,
+                                     Error **errp)
+{
+    if (!channel) {
+        error_setg(errp, "bad channel");
+        return;
+    }
+
+    notifier_remove(&channel->notifier);
+
+    if (xenevtchn_unbind(xendev->xeh, channel->local_port) < 0) {
+        error_setg_errno(errp, errno, "xenevtchn_unbind failed");
+    }
+
+    g_free(channel);
+}
+
 static void xen_device_unrealize(DeviceState *dev, Error **errp)
 {
     XenDevice *xendev = XEN_DEVICE(dev);
@@ -641,6 +716,12 @@ static void xen_device_unrealize(DeviceState *dev, Error **errp)
     xen_device_frontend_destroy(xendev);
     xen_device_backend_destroy(xendev);
 
+    if (xendev->xeh) {
+        qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), NULL, NULL, NULL);
+        xenevtchn_close(xendev->xeh);
+        xendev->xeh = NULL;
+    }
+
     if (xendev->xgth) {
         xengnttab_close(xendev->xgth);
         xendev->xgth = NULL;
@@ -657,6 +738,16 @@ static void xen_device_exit(Notifier *n, void *data)
     xen_device_unrealize(DEVICE(xendev), &error_abort);
 }
 
+static void xen_device_event(void *opaque)
+{
+    XenDevice *xendev = opaque;
+    unsigned long port = xenevtchn_pending(xendev->xeh);
+
+    notifier_list_notify(&xendev->event_notifiers, (void *)port);
+
+    xenevtchn_unmask(xendev->xeh, port);
+}
+
 static void xen_device_realize(DeviceState *dev, Error **errp)
 {
     XenDevice *xendev = XEN_DEVICE(dev);
@@ -697,6 +788,16 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
     xendev->feature_grant_copy =
         (xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0);
 
+    xendev->xeh = xenevtchn_open(NULL, 0);
+    if (!xendev->xeh) {
+        error_setg_errno(errp, errno, "failed xenevtchn_open");
+        goto unrealize;
+    }
+
+    notifier_list_init(&xendev->event_notifiers);
+    qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), xen_device_event, NULL,
+                        xendev);
+
     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 63a09b67ee..f83a95cebd 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -26,6 +26,9 @@ typedef struct XenDevice {
     XenWatch *frontend_state_watch;
     xengnttab_handle *xgth;
     bool feature_grant_copy;
+    xenevtchn_handle *xeh;
+    xenevtchn_port_or_error_t local_port;
+    NotifierList event_notifiers;
 } XenDevice;
 
 typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp);
@@ -104,4 +107,19 @@ void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
                                 XenDeviceGrantCopySegment segs[],
                                 unsigned int nr_segs, Error **errp);
 
+typedef struct XenEventChannel XenEventChannel;
+
+typedef void (*XenEventHandler)(void *opaque);
+
+XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
+                                               unsigned int port,
+                                               XenEventHandler handler,
+                                               void *opaque, Error **errp);
+void xen_device_notify_event_channel(XenDevice *xendev,
+                                     XenEventChannel *channel,
+                                     Error **errp);
+void xen_device_unbind_event_channel(XenDevice *xendev,
+                                     XenEventChannel *channel,
+                                     Error **errp);
+
 #endif /* HW_XEN_BUS_H */
-- 
2.20.1.2.gb21ebb6


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2018-12-17 13:30 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-17 13:29 [PATCH v6 00/18] Xen PV backend 'qdevification' Paul Durrant
2018-12-17 13:29 ` [PATCH v6 01/18] xen: re-name XenDevice to XenLegacyDevice Paul Durrant
2018-12-17 13:29 ` [PATCH v6 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy Paul Durrant
2018-12-17 13:29 ` [PATCH v6 03/18] xen: introduce 'xen-block', 'xen-disk' and 'xen-cdrom' Paul Durrant
2018-12-17 13:29 ` [PATCH v6 04/18] xen: create xenstore areas for XenDevice-s Paul Durrant
2018-12-17 13:29 ` [PATCH v6 05/18] xen: add xenstore watcher infrastructure Paul Durrant
2018-12-17 13:29 ` [PATCH v6 06/18] xen: add grant table interface for XenDevice-s Paul Durrant
2018-12-17 13:30 ` Paul Durrant [this message]
2018-12-17 13:30 ` [PATCH v6 08/18] xen: duplicate xen_disk.c as basis of dataplane/xen-block.c Paul Durrant
2018-12-17 13:30 ` [PATCH v6 09/18] xen: remove unnecessary code from dataplane/xen-block.c Paul Durrant
2018-12-17 13:30 ` [PATCH v6 10/18] xen: add header and build dataplane/xen-block.c Paul Durrant
2018-12-17 13:30 ` [PATCH v6 11/18] xen: remove 'XenBlkDev' and 'blkdev' names from dataplane/xen-block Paul Durrant
2018-12-17 13:30 ` [PATCH v6 12/18] xen: remove 'ioreq' struct/varable/field names from dataplane/xen-block.c Paul Durrant
2018-12-17 13:30 ` [PATCH v6 13/18] xen: purge 'blk' and 'ioreq' from function names in dataplane/xen-block.c Paul Durrant
2018-12-17 13:30 ` [PATCH v6 14/18] xen: add implementations of xen-block connect and disconnect functions Paul Durrant
2018-12-17 13:30 ` [PATCH v6 15/18] xen: add a mechanism to automatically create XenDevice-s Paul Durrant
2018-12-19 12:40   ` Anthony PERARD
2018-12-17 13:30 ` [PATCH v6 16/18] xen: automatically create XenBlockDevice-s Paul Durrant
2018-12-17 13:30 ` [PATCH v6 17/18] MAINTAINERS: add myself as a Xen maintainer Paul Durrant
2018-12-17 13:30 ` [PATCH v6 18/18] xen: remove the legacy 'xen_disk' backend Paul Durrant
     [not found] ` <20181217133011.31433-17-paul.durrant@citrix.com>
2018-12-19 12:39   ` [PATCH v6 16/18] xen: automatically create XenBlockDevice-s Anthony PERARD
     [not found]   ` <20181219123926.GA1288@perard.uk.xensource.com>
2018-12-19 12:43     ` Paul Durrant
     [not found]     ` <40bdef2962864ca8bc364249196bf9b3@AMSPEX02CL03.citrite.net>
2018-12-19 14:01       ` Anthony PERARD
2018-12-19 14:03         ` Paul Durrant

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=20181217133011.31433-8-paul.durrant@citrix.com \
    --to=paul.durrant@citrix.com \
    --cc=anthony.perard@citrix.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=sstabellini@kernel.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).