From nobody Thu Nov 6 19:44:19 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1542813292883710.3237492189945; Wed, 21 Nov 2018 07:14:52 -0800 (PST) Received: from localhost ([::1]:39686 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPUD6-0007W3-9G for importer@patchew.org; Wed, 21 Nov 2018 10:14:36 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46104) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gPUB3-0005Ss-CK for qemu-devel@nongnu.org; Wed, 21 Nov 2018 10:12:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gPUB1-0003fO-VM for qemu-devel@nongnu.org; Wed, 21 Nov 2018 10:12:29 -0500 Received: from smtp03.citrix.com ([162.221.156.55]:55932) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gPUAw-0003Ui-Nm; Wed, 21 Nov 2018 10:12:22 -0500 X-IronPort-AV: E=Sophos;i="5.56,261,1539648000"; d="scan'208";a="71205801" From: Paul Durrant To: , , Date: Wed, 21 Nov 2018 15:12:00 +0000 Message-ID: <20181121151211.15997-8-paul.durrant@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20181121151211.15997-1-paul.durrant@citrix.com> References: <20181121151211.15997-1-paul.durrant@citrix.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 162.221.156.55 Subject: [Qemu-devel] [PATCH 07/18] xen: add event channel interface for XenDevice-s X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Anthony Perard , Paul Durrant , Stefano Stabellini Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 --- Cc: Stefano Stabellini Cc: Anthony Perard --- hw/xen/xen-bus.c | 84 ++++++++++++++++++++++++++++++++++++++++++++= ++++ include/hw/xen/xen-bus.h | 16 +++++++++ 2 files changed, 100 insertions(+) diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index 7a152d2a2f..64c8af54b0 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -579,6 +579,65 @@ done: g_free(xengnttab_segs); } =20 +struct XenEventChannel { + unsigned int local_port; + XenEventHandler handler; + void *opaque; + Notifier notifier; +}; + +static void event_notify(Notifier *n, void *data) +{ + XenEventChannel *channel =3D container_of(n, XenEventChannel, notifier= ); + unsigned long port =3D (unsigned long)data; + + if (port =3D=3D 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 =3D g_new0(XenEventChannel, 1); + + channel->local_port =3D 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 =3D handler; + channel->opaque =3D opaque; + channel->notifier.notify =3D event_notify; + + notifier_list_add(&xendev->event_notifiers, &channel->notifier); + + return channel; +} + +void xen_device_notify_event_channel(XenDevice *xendev, + XenEventChannel *channel) +{ + xenevtchn_notify(xendev->xeh, channel->local_port); +} + +void xen_device_unbind_event_channel(XenDevice *xendev, + XenEventChannel *channel) +{ + notifier_remove(&channel->notifier); + + xenevtchn_unbind(xendev->xeh, channel->local_port); + + g_free(channel); +} + static void xen_device_unrealize(DeviceState *dev, Error **errp) { XenDevice *xendev =3D XEN_DEVICE(dev); @@ -602,6 +661,11 @@ static void xen_device_unrealize(DeviceState *dev, Err= or **errp) xen_device_frontend_destroy(xendev); xen_device_backend_destroy(xendev); =20 + if (xendev->xeh) { + qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), NULL, NULL, NULL); + xenevtchn_close(xendev->xeh); + } + if (xendev->xgth) { xengnttab_close(xendev->xgth); } @@ -616,6 +680,16 @@ static void xen_device_exit(Notifier *n, void *data) xen_device_unrealize(DEVICE(xendev), &error_abort); } =20 +static void xen_device_event(void *opaque) +{ + XenDevice *xendev =3D opaque; + unsigned long port =3D 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 =3D XEN_DEVICE(dev); @@ -656,6 +730,16 @@ static void xen_device_realize(DeviceState *dev, Error= **errp) xendev->feature_grant_copy =3D (xengnttab_grant_copy(xendev->xgth, 0, NULL) =3D=3D 0); =20 + xendev->xeh =3D 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 db14d49027..386f6bfc93 100644 --- a/include/hw/xen/xen-bus.h +++ b/include/hw/xen/xen-bus.h @@ -24,6 +24,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; =20 typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp); @@ -102,4 +105,17 @@ void xen_device_copy_grant_refs(XenDevice *xendev, boo= l to_domain, XenDeviceGrantCopySegment segs[], unsigned int nr_segs, Error **errp); =20 +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); +void xen_device_unbind_event_channel(XenDevice *xendev, + XenEventChannel *channel); + #endif /* HW_XEN_BUS_H */ --=20 2.11.0