[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 07/18] xen: add event channel interface for XenDe
From: |
Paul Durrant |
Subject: |
[Qemu-devel] [PATCH v2 07/18] xen: add event channel interface for XenDevice-s |
Date: |
Thu, 6 Dec 2018 15:08:33 +0000 |
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 <address@hidden>
---
Cc: Stefano Stabellini <address@hidden>
Cc: Anthony Perard <address@hidden>
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 b40dc83..0e6f194 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -621,6 +621,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);
@@ -649,6 +724,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;
@@ -665,6 +746,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);
@@ -705,6 +796,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 63a09b6..f83a95c 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.1.4
- Re: [Qemu-devel] [PATCH v2 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy, (continued)
- [Qemu-devel] [PATCH v2 08/18] xen: duplicate xen_disk.c as basis of dataplane/xen-block.c, Paul Durrant, 2018/12/06
- [Qemu-devel] [PATCH v2 05/18] xen: add xenstore watcher infrastructure, Paul Durrant, 2018/12/06
- [Qemu-devel] [PATCH v2 04/18] xen: create xenstore areas for XenDevice-s, Paul Durrant, 2018/12/06
- [Qemu-devel] [PATCH v2 09/18] xen: remove unnecessary code from dataplane/xen-block.c, Paul Durrant, 2018/12/06
- [Qemu-devel] [PATCH v2 07/18] xen: add event channel interface for XenDevice-s,
Paul Durrant <=
- [Qemu-devel] [PATCH v2 06/18] xen: add grant table interface for XenDevice-s, Paul Durrant, 2018/12/06
- [Qemu-devel] [PATCH v2 03/18] xen: introduce 'xen-block', 'xen-disk' and 'xen-cdrom', Paul Durrant, 2018/12/06
- Re: [Qemu-devel] [PATCH v2 03/18] xen: introduce 'xen-block', 'xen-disk' and 'xen-cdrom', Anthony PERARD, 2018/12/07
- Re: [Qemu-devel] [PATCH v2 03/18] xen: introduce 'xen-block', 'xen-disk' and 'xen-cdrom', Paul Durrant, 2018/12/07
- Re: [Qemu-devel] [PATCH v2 03/18] xen: introduce 'xen-block', 'xen-disk' and 'xen-cdrom', Anthony PERARD, 2018/12/07
- Re: [Qemu-devel] [PATCH v2 03/18] xen: introduce 'xen-block', 'xen-disk' and 'xen-cdrom', Daniel P . Berrangé, 2018/12/07
- Re: [Qemu-devel] [PATCH v2 03/18] xen: introduce 'xen-block', 'xen-disk' and 'xen-cdrom', Paul Durrant, 2018/12/10
[Qemu-devel] [PATCH v2 15/18] xen: add a mechanism to automatically create XenDevice-s..., Paul Durrant, 2018/12/06